Import upstream gpsbabel version 1.2.5+1.2.6-beta20050608
authorJohn Goerzen <jgoerzen@complete.org>
Tue, 21 Jun 2005 13:57:03 +0000 (13:57 +0000)
committerJohn Goerzen <jgoerzen@complete.org>
Tue, 21 Jun 2005 13:57:03 +0000 (13:57 +0000)
176 files changed:
Makefile
README
an1.c [new file with mode: 0644]
an1sym.h [new file with mode: 0644]
arcdist.c
brauniger_iq.c
cetus.c
chkdoc
coastexp.c [new file with mode: 0644]
coldsync/pdb.c
coldsync/util.c
copilot.c
csv_util.c
csv_util.h
defs.h
delgpl.c
duplicate.c
easygps.c
filter_vecs.c
garmin.c
garmin_tables.c
gbtypes.h [new file with mode: 0644]
gcdb.c
geo.c
geoniche.c
glogbook.c [new file with mode: 0644]
google.c [new file with mode: 0644]
gpilots.c
gpspilot.c
gpsutil.c
gpx.c
gpxval
hiketech.c [new file with mode: 0644]
holux.c
hsa_ndv.c
html.c
igc.c
intdoc/GPSBabel Windows GUI 2.00.00 Project Plan.pdf [new file with mode: 0644]
intdoc/SA2003_an1_dump.pl [new file with mode: 0644]
internal_styles.c
jeeps/gps.h
jeeps/gpsapp.c
jeeps/gpscom.c
jeeps/gpscom.h
jeeps/gpsinput.c
jeeps/gpslibusb.c
jeeps/gpsmem.c
jeeps/gpsport.h
jeeps/gpsprot.c
jeeps/gpsprot.h
jeeps/gpsread.c
jeeps/gpsread.h
jeeps/gpssend.c
jeeps/gpsserial.c
jeeps/gpsserial.h
jeeps/gpsusbint.h [new file with mode: 0644]
jeeps/gpsusbread.c
jeeps/gpsusbsend.c
jeeps/gpsusbwin.c
kml.c [new file with mode: 0644]
lowranceusr.c [new file with mode: 0644]
macgpsbabel/Credits.rtf
macgpsbabel/English.lproj/MainMenu.nib/objects.nib
macgpsbabel/MacGPSBabel.applescript
macgpsbabel/MacGPSBabel.pbproj/project.pbxproj
magellan.h
maggeo.c [new file with mode: 0644]
magnav.c
magproto.c
main.c
make-an1sym.pl [new file with mode: 0644]
mapopolis.c
mapsend.c
mapsource.c
mingw/Makefile
mingw/wintesto.cmd
mkshort.c
msvc/GPSBabel.dsp
msvc/GPSBabel.vcproj
navicache.c
netstumbler.c
nmea.c
overlay.c [new file with mode: 0644]
ozi.c
palmdoc.c
pathaway.c [new file with mode: 0644]
pcx.c
position.c
psitrex.c
psp.c
queue.h
quovadis.c
reference/Glad_5.exp
reference/an1-an1.ref [new file with mode: 0644]
reference/an1-in.ref [new file with mode: 0644]
reference/an1-line-out.ref [new file with mode: 0644]
reference/an1-out.ref [new file with mode: 0644]
reference/coastexp.nob [new file with mode: 0644]
reference/coastexp.ref [new file with mode: 0644]
reference/coastexp.ref2 [new file with mode: 0644]
reference/coastexp.ref3 [new file with mode: 0644]
reference/coastexp.ref4 [new file with mode: 0644]
reference/foo.an1 [new file with mode: 0644]
reference/google.arc [new file with mode: 0644]
reference/google.js [new file with mode: 0644]
reference/google.xml [new file with mode: 0644]
reference/googmap.sh [new file with mode: 0644]
reference/googmapjs.sh [new file with mode: 0644]
reference/hsandv.exp
reference/igc1.gpx
reference/igc1_3d.out
reference/igc1_gpx.out
reference/igc1_igc.out
reference/igc2_gpx.out
reference/lowrance.usr [new file with mode: 0644]
reference/ov2-arc-out.ref [new file with mode: 0644]
reference/ov2-geo-out.ref [new file with mode: 0644]
reference/ov2-in.ref [new file with mode: 0644]
reference/pathaway-geo.loc [new file with mode: 0644]
reference/route/route.gpx
reference/route/tef_xml.mps [new file with mode: 0644]
reference/route/tef_xml.sample.xml [new file with mode: 0644]
reference/track/TrkDB-GPil.pdb [new file with mode: 0644]
reference/track/pathaway.mps [new file with mode: 0644]
reference/track/pathaway.pdb [new file with mode: 0644]
reference/track/tef_xml.sample.xml [new file with mode: 0644]
route.c
saroute.c
shape.c
stackfilter.c
style/README.style
style/csv.style
style/s_and_t.style
style/saplus.style
style/tabsep.style
style/xmap.style
style/xmapwpt.style
tef_xml.c [new file with mode: 0644]
testo
text.c
tiger.c
tmpro.c
tomtom.c [new file with mode: 0644]
tools/memdebug
tools/mkchanges
tpg.c
util.c
uuid.c [new file with mode: 0644]
uuid.h [new file with mode: 0644]
vcf.c [new file with mode: 0644]
vecs.c
waypt.c
win32/GPSBabelGUI.exe [new file with mode: 0644]
win32/README [deleted file]
win32/gpsbabelfront.dpr [deleted file]
win32/gpsbabelfront.exe [deleted file]
win32/gpsbabelfront_mainform.dfm [deleted file]
win32/gpsbabelfront_mainform.pas [deleted file]
win32/gui/AboutDialogU.ddp [new file with mode: 0644]
win32/gui/AboutDialogU.dfm [new file with mode: 0644]
win32/gui/AboutDialogU.pas [new file with mode: 0644]
win32/gui/GPSBabelGUI.cfg [new file with mode: 0644]
win32/gui/GPSBabelGUI.dof [new file with mode: 0644]
win32/gui/GPSBabelGUI.dpr [new file with mode: 0644]
win32/gui/GPSBabelGUI.ico [new file with mode: 0644]
win32/gui/GPSBabelGUI.res [new file with mode: 0644]
win32/gui/GPSBabelGUI.todo [new file with mode: 0644]
win32/gui/GPSBabelGUIDialogU.ddp [new file with mode: 0644]
win32/gui/GPSBabelGUIDialogU.dfm [new file with mode: 0644]
win32/gui/GPSBabelGUIDialogU.pas [new file with mode: 0644]
win32/gui/README.txt [new file with mode: 0644]
win32/gui/VersionInfo.pas [new file with mode: 0644]
win32/gui/filelist.txt [new file with mode: 0644]
xcsv.c
xmlgeneric.c [new file with mode: 0644]
xmlgeneric.h [new file with mode: 0644]

index 35ac1039a147f9ce416cd1328e0d33602bf02285..733986566c25e588ed7b7abb0502f04212609381 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,8 @@ LIBEXPAT=-lexpat # -lefence
 # USB may required non-standard libraries (like libusb) be installed
 # and may not be available on all OSes.  Uncomment this to remove the key
 # parts of USB from the build.
-INHIBIT_USB=-DNO_USB
+INHIBIT_USB=#-DNO_USB
+LIBUSB=-lusb
 
 #
 # Enable either or both of these as you wish.
@@ -25,7 +26,9 @@ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin_tables.o \
        xcsv.o gcdb.o tiger.o internal_styles.o easygps.o quovadis.o \
        gpilots.o saroute.o navicache.o psitrex.o geoniche.o delgpl.o \
        ozi.o nmea.o text.o html.o palmdoc.o netstumbler.o hsa_ndv.o \
-       igc.o brauniger_iq.o shape.o
+       igc.o brauniger_iq.o shape.o hiketech.o glogbook.o coastexp.o \
+       vcf.o overlay.o kml.o google.o lowranceusr.o an1.o tomtom.o \
+       tef_xml.o maggeo.o pathaway.o
 
 FILTERS=position.o duplicate.o arcdist.o polygon.o smplrout.o reverse_route.o sort.o stackfilter.o
 
@@ -44,7 +47,7 @@ COLDSYNC=coldsync/util.o coldsync/pdb.o
 SHAPE=shapelib/shpopen.o shapelib/dbfopen.o
 
 LIBOBJS = queue.o route.o waypt.o filter_vecs.o util.o vecs.o mkshort.o \
-          csv_util.o grtcirc.o vmem.o util_crc.o \
+          csv_util.o grtcirc.o vmem.o util_crc.o xmlgeneric.o uuid.o \
        $(COLDSYNC) $(GARMIN) $(JEEPS) $(SHAPE) $(FMTS) $(FILTERS)
 OBJS = main.o $(LIBOBJS)
 
@@ -54,7 +57,7 @@ OBJS = main.o $(LIBOBJS)
 all: gpsbabel
 
 gpsbabel: $(OBJS)
-       $(CC) $(CFLAGS) $(OBJS) -o gpsbabel $(LIBEXPAT) -lm
+       $(CC) $(CFLAGS) $(OBJS) -o gpsbabel $(LIBEXPAT) $(LIBUSB) -lm
 
 main.o:
        $(CC) -c $(CFLAGS) -DVERSION=\"$(VERSIOND)\" $<
@@ -88,10 +91,10 @@ dep:
        (echo -n "internal_styles.c: mkstyle.sh " ; echo style/*.style ; /bin/echo -e '\t./mkstyle.sh > internal_styles.c || (rm -f internal_styles.c ; exit 1)' ) >> /tmp/dep
        echo Edit Makefile and bring in /tmp/dep
 
-#VERSIONU=1_2_4_beta10162004
-#VERSIOND=1.2.4_beta10162004
-VERSIONU=1_2_4
-VERSIOND=1.2.4
+VERSIONU=1_2_6-beta06082005
+VERSIOND=1.2.6_beta06082005
+# VERSIONU=1_2_5
+# VERSIOND=1.2.5
 
 release:
        cvs commit
@@ -107,8 +110,11 @@ release:
        curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).tar.gz ftp://upload.sf.net/incoming/
        curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).zip ftp://upload.sf.net/incoming/
 
+mac-usbfree:
+       make LIBEXPAT=/sw/lib/libexpat.a EXTRA_CFLAGS="-I/sw/include" LIBUSB= INHIBIT_USB=-DNO_USB
+
 mac-build:
-       make LIBEXPAT=/sw/lib/libexpat.a EXTRA_CFLAGS="-I/sw/include"
+       make LIBEXPAT=/sw/lib/libexpat.a EXTRA_CFLAGS="-I/sw/include" LIBUSB="/sw/lib/libusb.a -lIOKit  -lBSDPClient -framework CoreFoundation"
 
 mac-release:
        mkdir -p usr/bin usr/share/gpsbabel/doc
@@ -119,165 +125,197 @@ mac-release:
 
 # Machine generated from here down.  
 
-arcdist.o: arcdist.c defs.h queue.h grtcirc.h
-brauniger_iq.o: brauniger_iq.c defs.h queue.h jeeps/gpsserial.h \
+an1.o: an1.c defs.h queue.h gbtypes.h an1sym.h
+arcdist.o: arcdist.c defs.h queue.h gbtypes.h grtcirc.h
+brauniger_iq.o: brauniger_iq.c defs.h queue.h gbtypes.h jeeps/gpsserial.h \
   jeeps/gps.h jeeps/gpsport.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
   jeeps/gpsnmeaget.h
-cetus.o: cetus.c defs.h queue.h coldsync/palm.h coldsync/pdb.h
-copilot.o: copilot.c defs.h queue.h coldsync/palm.h coldsync/pdb.h
-csv_util.o: csv_util.c defs.h queue.h csv_util.h grtcirc.h
-delgpl.o: delgpl.c defs.h queue.h
-duplicate.o: duplicate.c defs.h queue.h
-easygps.o: easygps.c defs.h queue.h
-filter_vecs.o: filter_vecs.c defs.h queue.h
-garmin.o: garmin.c defs.h queue.h jeeps/gps.h jeeps/gpsport.h \
+cetus.o: cetus.c defs.h queue.h gbtypes.h coldsync/palm.h coldsync/pdb.h
+coastexp.o: coastexp.c defs.h queue.h gbtypes.h xmlgeneric.h uuid.h
+copilot.o: copilot.c defs.h queue.h gbtypes.h coldsync/palm.h \
+  coldsync/pdb.h
+csv_util.o: csv_util.c defs.h queue.h gbtypes.h csv_util.h grtcirc.h
+delgpl.o: delgpl.c defs.h queue.h gbtypes.h
+duplicate.o: duplicate.c defs.h queue.h gbtypes.h
+easygps.o: easygps.c defs.h queue.h gbtypes.h
+filter_vecs.o: filter_vecs.c defs.h queue.h gbtypes.h
+garmin.o: garmin.c defs.h queue.h gbtypes.h jeeps/gps.h jeeps/gpsport.h \
   jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
   jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
   jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
   jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h \
   garmin_tables.h
 garmin_tables.o: garmin_tables.c garmin_tables.h
-gcdb.o: gcdb.c defs.h queue.h coldsync/palm.h coldsync/pdb.h
-geo.o: geo.c defs.h queue.h
-geoniche.o: geoniche.c defs.h queue.h coldsync/palm.h coldsync/pdb.h
-gpilots.o: gpilots.c defs.h queue.h coldsync/palm.h coldsync/pdb.h \
-  garmin_tables.h
-gpspilot.o: gpspilot.c defs.h queue.h coldsync/palm.h coldsync/pdb.h
-gpsutil.o: gpsutil.c defs.h queue.h magellan.h
-gpx.o: gpx.c defs.h queue.h
-grtcirc.o: grtcirc.c defs.h queue.h
-holux.o: holux.c defs.h queue.h holux.h
-hsa_ndv.o: hsa_ndv.c defs.h queue.h
-html.o: html.c defs.h queue.h jeeps/gpsmath.h jeeps/gps.h jeeps/gpsport.h \
-  jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \
-  jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
-igc.o: igc.c defs.h queue.h
-internal_styles.o: internal_styles.c defs.h queue.h
-magnav.o: magnav.c defs.h queue.h coldsync/palm.h coldsync/pdb.h
-magproto.o: magproto.c defs.h queue.h magellan.h
-main.o: main.c defs.h queue.h
-mapsend.o: mapsend.c defs.h queue.h mapsend.h magellan.h
-mapsource.o: mapsource.c defs.h queue.h garmin_tables.h
-mkshort.o: mkshort.c defs.h queue.h
-navicache.o: navicache.c defs.h queue.h
-netstumbler.o: netstumbler.c defs.h queue.h csv_util.h
-nmea.o: nmea.c defs.h queue.h
-ozi.o: ozi.c defs.h queue.h csv_util.h
-palmdoc.o: palmdoc.c defs.h queue.h jeeps/gpsmath.h jeeps/gps.h \
+gcdb.o: gcdb.c defs.h queue.h gbtypes.h coldsync/palm.h coldsync/pdb.h
+geo.o: geo.c defs.h queue.h gbtypes.h xmlgeneric.h
+geoniche.o: geoniche.c defs.h queue.h gbtypes.h coldsync/palm.h \
+  coldsync/pdb.h
+glogbook.o: glogbook.c defs.h queue.h gbtypes.h xmlgeneric.h
+google.o: google.c defs.h queue.h gbtypes.h xmlgeneric.h
+gpilots.o: gpilots.c defs.h queue.h gbtypes.h coldsync/palm.h \
+  coldsync/pdb.h garmin_tables.h
+gpspilot.o: gpspilot.c defs.h queue.h gbtypes.h coldsync/palm.h \
+  coldsync/pdb.h
+gpsutil.o: gpsutil.c defs.h queue.h gbtypes.h magellan.h
+gpx.o: gpx.c defs.h queue.h gbtypes.h xmlgeneric.h
+grtcirc.o: grtcirc.c defs.h queue.h gbtypes.h
+hiketech.o: hiketech.c defs.h queue.h gbtypes.h xmlgeneric.h
+holux.o: holux.c defs.h queue.h gbtypes.h holux.h
+hsa_ndv.o: hsa_ndv.c defs.h queue.h gbtypes.h
+html.o: html.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \
+  jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
+  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+  jeeps/gpsfmt.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
+  jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
+igc.o: igc.c defs.h queue.h gbtypes.h
+internal_styles.o: internal_styles.c defs.h queue.h gbtypes.h
+kml.o: kml.c defs.h queue.h gbtypes.h xmlgeneric.h
+lowranceusr.o: lowranceusr.c defs.h queue.h gbtypes.h
+magnav.o: magnav.c defs.h queue.h gbtypes.h coldsync/palm.h \
+  coldsync/pdb.h
+magproto.o: magproto.c defs.h queue.h gbtypes.h magellan.h
+main.o: main.c defs.h queue.h gbtypes.h
+tef_xml.o: tef_xml.c defs.h queue.h gbtypes.h xmlgeneric.h
+pathaway.o: pathaway.c defs.h queue.h gbtypes.h \
+  coldsync/palm.h coldsync/pdb.h csv_util.h
+mapsend.o: mapsend.c defs.h queue.h gbtypes.h mapsend.h magellan.h
+mapsource.o: mapsource.c defs.h queue.h gbtypes.h garmin_tables.h
+mkshort.o: mkshort.c defs.h queue.h gbtypes.h
+navicache.o: navicache.c defs.h queue.h gbtypes.h
+netstumbler.o: netstumbler.c defs.h queue.h gbtypes.h csv_util.h
+nmea.o: nmea.c defs.h queue.h gbtypes.h
+overlay.o: overlay.c defs.h queue.h gbtypes.h grtcirc.h
+ozi.o: ozi.c defs.h queue.h gbtypes.h csv_util.h
+palmdoc.o: palmdoc.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
   jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h \
   coldsync/palm.h coldsync/pdb.h
-pcx.o: pcx.c defs.h queue.h garmin_tables.h
-polygon.o: polygon.c defs.h queue.h
-position.o: position.c defs.h queue.h grtcirc.h
-psitrex.o: psitrex.c defs.h queue.h garmin_tables.h
-psp.o: psp.c defs.h queue.h
+pcx.o: pcx.c defs.h queue.h gbtypes.h garmin_tables.h
+polygon.o: polygon.c defs.h queue.h gbtypes.h
+position.o: position.c defs.h queue.h gbtypes.h grtcirc.h
+psitrex.o: psitrex.c defs.h queue.h gbtypes.h garmin_tables.h
+psp.o: psp.c defs.h queue.h gbtypes.h
 queue.o: queue.c queue.h
-quovadis.o: quovadis.c quovadis.h defs.h queue.h coldsync/palm.h \
-  coldsync/pdb.h
-reverse_route.o: reverse_route.c defs.h queue.h
-route.o: route.c defs.h queue.h
-saroute.o: saroute.c defs.h queue.h
-shape.o: shape.c defs.h queue.h shapelib/shapefil.h
-smplrout.o: smplrout.c defs.h queue.h grtcirc.h
-sort.o: sort.c defs.h queue.h
-stackfilter.o: stackfilter.c defs.h queue.h
-text.o: text.c defs.h queue.h jeeps/gpsmath.h jeeps/gps.h jeeps/gpsport.h \
-  jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \
-  jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
-tiger.o: tiger.c defs.h queue.h csv_util.h
-tmpro.o: tmpro.c defs.h queue.h csv_util.h
-tpg.o: tpg.c defs.h queue.h jeeps/gpsmath.h jeeps/gps.h jeeps/gpsport.h \
-  jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \
-  jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
-util.o: util.c defs.h queue.h
+quovadis.o: quovadis.c quovadis.h defs.h queue.h gbtypes.h \
+  coldsync/palm.h coldsync/pdb.h
+reverse_route.o: reverse_route.c defs.h queue.h gbtypes.h
+route.o: route.c defs.h queue.h gbtypes.h
+saroute.o: saroute.c defs.h queue.h gbtypes.h
+shape.o: shape.c defs.h queue.h gbtypes.h shapelib/shapefil.h
+smplrout.o: smplrout.c defs.h queue.h gbtypes.h grtcirc.h
+sort.o: sort.c defs.h queue.h gbtypes.h
+stackfilter.o: stackfilter.c defs.h queue.h gbtypes.h
+text.o: text.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \
+  jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
+  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+  jeeps/gpsfmt.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
+  jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
+tiger.o: tiger.c defs.h queue.h gbtypes.h csv_util.h
+tmpro.o: tmpro.c defs.h queue.h gbtypes.h csv_util.h
+tomtom.o: tomtom.c defs.h queue.h gbtypes.h
+tpg.o: tpg.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \
+  jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
+  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+  jeeps/gpsfmt.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
+  jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
+util.o: util.c defs.h queue.h gbtypes.h
 util_crc.o: util_crc.c
-vecs.o: vecs.c defs.h queue.h csv_util.h
-vmem.o: vmem.c defs.h queue.h
-waypt.o: waypt.c defs.h queue.h
-xcsv.o: xcsv.c defs.h queue.h csv_util.h
+uuid.o: uuid.c uuid.h
+vcf.o: vcf.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \
+  jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
+  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+  jeeps/gpsfmt.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
+  jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
+vecs.o: vecs.c defs.h queue.h gbtypes.h csv_util.h
+vmem.o: vmem.c defs.h queue.h gbtypes.h
+waypt.o: waypt.c defs.h queue.h gbtypes.h
+xcsv.o: xcsv.c defs.h queue.h gbtypes.h csv_util.h
+xmlgeneric.o: xmlgeneric.c defs.h queue.h gbtypes.h xmlgeneric.h
 coldsync/pdb.o: coldsync/pdb.c coldsync/config.h coldsync/palm.h \
   coldsync/pdb.h
 coldsync/util.o: coldsync/util.c coldsync/config.h coldsync/pconn/util.h \
   coldsync/palm.h
-jeeps/gpsapp.o: jeeps/gpsapp.c jeeps/gps.h defs.h queue.h jeeps/gpsport.h \
-  jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
-jeeps/gpscom.o: jeeps/gpscom.c jeeps/gps.h defs.h queue.h jeeps/gpsport.h \
-  jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h
-jeeps/gpslibusb.o: jeeps/gpslibusb.c
-jeeps/gpsmath.o: jeeps/gpsmath.c jeeps/gps.h defs.h queue.h \
+jeeps/gpsapp.o: jeeps/gpsapp.c jeeps/gps.h defs.h queue.h gbtypes.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
-  jeeps/gpsnmeaget.h jeeps/gpsdatum.h
-jeeps/gpsmem.o: jeeps/gpsmem.c jeeps/gps.h defs.h queue.h jeeps/gpsport.h \
-  jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h \
-  jeeps/garminusb.h
-jeeps/gpsprot.o: jeeps/gpsprot.c jeeps/gps.h defs.h queue.h \
+  jeeps/gpsnmeaget.h
+jeeps/gpscom.o: jeeps/gpscom.c jeeps/gps.h defs.h queue.h gbtypes.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
   jeeps/gpsnmeaget.h
-jeeps/gpsread.o: jeeps/gpsread.c jeeps/gps.h defs.h queue.h \
+jeeps/gpslibusb.o: jeeps/gpslibusb.c jeeps/gps.h defs.h queue.h gbtypes.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
-  jeeps/gpsnmeaget.h
-jeeps/gpsrqst.o: jeeps/gpsrqst.c jeeps/gps.h defs.h queue.h \
+  jeeps/gpsnmeaget.h jeeps/garminusb.h
+jeeps/gpsmath.o: jeeps/gpsmath.c jeeps/gps.h defs.h queue.h gbtypes.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
-  jeeps/gpsnmeaget.h
-jeeps/gpssend.o: jeeps/gpssend.c jeeps/gps.h defs.h queue.h \
+  jeeps/gpsnmeaget.h jeeps/gpsdatum.h
+jeeps/gpsmem.o: jeeps/gpsmem.c jeeps/gps.h defs.h queue.h gbtypes.h \
+  jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
+  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
+  jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
+  jeeps/gpsnmeaget.h jeeps/garminusb.h
+jeeps/gpsprot.o: jeeps/gpsprot.c jeeps/gps.h defs.h queue.h gbtypes.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
   jeeps/gpsnmeaget.h
-jeeps/gpsserial.o: jeeps/gpsserial.c jeeps/gps.h defs.h queue.h \
+jeeps/gpsread.o: jeeps/gpsread.c jeeps/gps.h defs.h queue.h gbtypes.h \
+  jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
+  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
+  jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
+  jeeps/gpsnmeaget.h jeeps/gpsusbint.h
+jeeps/gpsrqst.o: jeeps/gpsrqst.c jeeps/gps.h defs.h queue.h gbtypes.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
   jeeps/gpsnmeaget.h
-jeeps/gpsusbread.o: jeeps/gpsusbread.c jeeps/gps.h defs.h queue.h \
+jeeps/gpssend.o: jeeps/gpssend.c jeeps/gps.h defs.h queue.h gbtypes.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
-  jeeps/gpsnmeaget.h jeeps/garminusb.h
-jeeps/gpsusbsend.o: jeeps/gpsusbsend.c jeeps/gps.h defs.h queue.h \
+  jeeps/gpsnmeaget.h jeeps/gpsusbint.h
+jeeps/gpsserial.o: jeeps/gpsserial.c jeeps/gps.h defs.h queue.h gbtypes.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \
   jeeps/gpsnmeaget.h jeeps/garminusb.h
-jeeps/gpsusbstub.o: jeeps/gpsusbstub.c jeeps/garminusb.h
-jeeps/gpsutil.o: jeeps/gpsutil.c jeeps/gps.h defs.h queue.h \
+jeeps/gpsusbread.o: jeeps/gpsusbread.c jeeps/gps.h defs.h queue.h \
+  gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h \
+  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
+  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h \
+  jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \
+  jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/garminusb.h \
+  jeeps/gpsusbint.h
+jeeps/gpsusbsend.o: jeeps/gpsusbsend.c jeeps/gps.h defs.h queue.h \
+  gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h \
+  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
+  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h \
+  jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \
+  jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/garminusb.h \
+  jeeps/gpsusbint.h
+jeeps/gpsusbstub.o: jeeps/gpsusbstub.c
+jeeps/gpsutil.o: jeeps/gpsutil.c jeeps/gps.h defs.h queue.h gbtypes.h \
   jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
   jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \
diff --git a/README b/README
index bd6cf7ac58a8176003032e708593b31478c67350..164cb44fa89c810892e69bcadb0de32a1d6aae44 100644 (file)
--- a/README
+++ b/README
@@ -1,12 +1,12 @@
 
 THE PROBLEM
 
-        There are simply too many gratituosuly different file formats to
+        There are simply too many gratuitously different file formats to
         hold waypoint, track, and route information in various programs
         used by computers.  GPX (http://www.topografix.com/gpx.asp)
-        attempts to define a standard in XML to contain all the data,
-        but there are too many programs that don't understand it yet and
-        too much data that are in an alternate format.
+        defines a standard in XML to contain all the data, but there
+        are too many programs that don't understand it yet and
+        too much data that are in an alternate formats.
 
 THE SOLUTION
 
@@ -37,6 +37,79 @@ GETTING IT / BUILDING IT
         Exapt can be downloaded from http://expat.sourceforge.net and is
         part of Apache so it's very portable.
 
+COMMON USAGE
+
+       Invocation was meant to be flexible.   Unfortunately, that can
+       sometimes lead to unwieldy command lines.
+
+               gpsbabel -? 
+
+       will always show you the supported file types.   To use this
+       program, just tell it what you're reading, where to read it from,
+       what you're writing, and what to write it to.  For example:
+
+       gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx
+
+       tells it to read the first file in geocaching.com format and create
+       a new file in GPX format.
+
+       This command will read from a Magellan unit attached to the first
+       serial port on a Linux system (device names will vary on other OSes)
+       and write them as a geocaching loc file.  The second command does 
+       the same for windows.
+
+       gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc
+       gpsbabel -i magellan -f com1 -o geo -F mag.loc
+       
+    PathAway (Palm) database
+    
+       PathAway is a Palm software designed for handling "most" GPS devices 
+       (including BlueTooth). In this time (i mean 2005) a free tool 
+       to convert this database is located on the homepage 
+       of PathAway (www.pathaway.com). But i've read there ... for windows and
+       the output format was also very limited. 
+
+       Optionally, you may specify "-s" in any command line.  This causes
+       the program to ignore any "short" names that may be present in the
+       source data format and synthesize one from the long name.  This
+       is particularly useful if you're writing to a target format that 
+       isn't the lowest common denominator but the source data was written
+       for the lowest common denominator.   I use this for writing data
+       from geocaching.com to my Magellan so my waypoints have "real" names
+       instead of the 'GC1234' ones that are optimized for NMEA-only 
+       receivers.   A geocacher with a Magellan receiver may thus find
+       commands like this useful.
+
+       gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0 
+       gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1
+
+ADVANCED USAGE
+
+       Argument are processed in the order they appear on the command line.
+       Input is cumulative.  The input file type remains unchanged until a 
+       new -i argument is seen.  Files are read in the order they appear.  
+       So you could merge three input files into one output file with:
+       
+       gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc
+
+       You can merge files of different types:
+
+       gpsbabel  -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx -o gpsutil -F big.gps
+
+       You can write the same data in different output formats:
+
+       gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx 1.wpt
+
+ROUTE AND TRACK MODES
+
+        The presence of "-t" on the command line tells us to work with
+        tracks.  The presence of "-r" tells us to work with routes.
+        Tracks and routes are advanced features and don't try to
+        handle every possible hazard that can be encountered during a
+        conversion.  If you're merging or converting files of similar
+        limitations, things work very well.  The presence of "-s" on
+        the command line tends to creat havoc because tracks and routes.
+
 THE FORMATS
 
     GPX
@@ -68,6 +141,15 @@ THE FORMATS
        Additional sub options:
        baud: may be 1200, 2400, 4800, 9600, 19200, but must match receiver.
 
+    MAGELLANX
+
+       The SD card format used by the Magellan Explorist 300, 400, and 500.
+       It's identical to the Magellan SD format used by Meridian, but allows
+       longer waypoint names.
+       
+       You should name any file created with this format with a ".upt"
+       extension so the firmware can read it.
+
     GARMIN
 
         Waypoint serial upload and download works reliably under both
@@ -102,8 +184,6 @@ THE FORMATS
        dumps by adding "-D9" to the command line, like:
 
                gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx
-       
-
 
     GPSMAN
 
@@ -131,10 +211,18 @@ THE FORMATS
        is the one that makes Delorme S&A Deluxe 9 happy.   It's also a very
        simple program and useful for many other programs like spreadsheets.
 
-        CSV is also the correct format for Lowrance MapCreate, their
-        commercial mapping program, or GDM6 (their free waypoint
-        manager) for iFinder which is available at 
-       http://www.lowrance.com/Software/GDM6/Default.asp
+        CSV is also the correct format for Lowrance MapCreate,
+        their commercial mapping program, or GDM6 (their free
+        waypoint manager) for iFinder which is available at
+        http://www.lowrance.com/Software/GDM6/Default.asp
+
+    LowranceUSR
+
+       The Lowrance iFinder GPS series has the unique capability to
+       output its data to an MMC card.  The data is saved to the card
+       as a .USR file and can be read by your computer using a card
+       reader.  Currently only reading and writing of waypoints (no
+       routes or tracks) is supported.
 
     XMap
 
@@ -473,6 +561,13 @@ THE FORMATS
 
        http://www.navicache.com/cgi-bin/ib312a/ikonboard.cgi?act=ST;f=23;t=334
 
+    coastexp
+
+       This is the format used by CoastalExplorer (tm). The format is
+       XML with items uniquely identified by Windows-style UUIDs.
+
+       http://www.rosepointnav.com
+
     PsiTrex
        
        This is a text format created by KuDaTa's PsiTrex program for the Psion
@@ -640,7 +735,109 @@ THE FORMATS
 
         HSA Systems Endeavour Navigator format - will import both the old
         version 4.x binary files, and the newer XML based ones. 
-        Only writes the new XML (5.0 and above) format. (use the .exp extension)
+        Only writes the new XML (5.0 and above) format. (use the .exp 
+       extension)
+
+    vCARD
+
+        The vCard output is intended to be in a format that enables
+        waypoints to be viewed with an Apple iPod. This is achieved by
+        mapping waypoint fields into vCard fields that can be displayed
+        as 'Contacts' on the iPod. With the iPod mounted as a hard disk
+        (see your iPod manual for instructions), the resulting VCF
+        file should be moved into the iPod 'Contacts' folder. As an
+        alternative, Mac OS X users may prefer to drag the VCF file into
+        their address book and synchronize with the iPod using iSync. By
+       default hints are unencrypted; use the 'encrypt' option to
+        encrypt the hints.
+
+    Hiketech
+
+        This is the .gps format used by the Mac OS X applications
+        written by HikeTech. These include TopoDraw, Link2GPS, and
+        GPSWrite. More information about these products can be found at
+        http://www.hiketech.com
+
+    glogbook
+
+        This is the XML format used by the Garmin Logbook product that
+        ships with Forerunner and Foretrex.
+
+       http://www.garmin.com
+
+    KML
+
+       We have sketchy support for KML, the Keyhole Markup Language.
+       There are many features in this file format that we don't yet
+       support, but simple waypoint lists convert fine.
+
+    GOOGLE
+        
+        This format is designed to read the XML emitted when you tack
+        "&output=js" onto the end of a Google Maps route URL (use the 
+        "link to this page" option to get a usable URL.)  This allows 
+        you to plan a route using Google Maps, then download it and use 
+        it in your own mapping program or GPS receiver.  If you use a 
+        Unix-compatible operating system, this shell script might be 
+        useful:
+
+        #!/bin/sh
+        FROM="233 S. Wacker, Chicago, IL"
+        TO="1060 W. Addison, Chicago, IL"
+        wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" \
+           2>/dev/null >google_map.js
+
+        gpsbabel -i google -f google_map.js -o gpx -F google_map.gpx
+       
+    TourExchangeFormat
+    
+       XML based export format, used by Map&Guide
+       "Motorrad-Routenplaner". This software can only export routing data.
+       So we don't support writing.
+       
+    PathAway
+    
+       PathAway is a Palm software designed for handling "most" GPS devices 
+       (including BlueTooth). In this time (i mean 2005) a free tool 
+       to convert this database is located on the homepage 
+       of PathAway (www.pathaway.com). But i've read there ... for windows and
+       the output formats are also very limited. 
+
+    AN1
+
+        This format supports the DeLorme ".an1" drawing file format.  It
+        can currently be used to either read or write drawing files.  If
+        you use this format to create drawing files with routes or waypoints
+        from another source, it will currently create "Red Flag" symbols 
+        for waypoints, and thick red lines for routes or tracks.  It is
+        possible to merge two drawing layers by doing something like this:
+
+        gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1
+
+        In this case, the merged data will contain all of the properties
+        of the original data.
+
+        Currently, GPSBabel only writes drawing layers, as opposed to road, 
+        track, and other specialized layers.  If your input file is a road, 
+        track, trail, or waypoint layer, you should not attempt to write to 
+        an .an1 file as the results may be unpredictable.  Note that this 
+        also applies to merging files, so you can't currently merge two road
+        layers with GPSBabel (officially; there is an unsupported "type" 
+        option that works in limited cases.)
+
+    TomTom
+
+       This format can read and write TomTom .ov2 (POI) files, as used by the 
+        TomTom GO and TomTom Navigator.  It has been tested with an original
+        TomTom GO running version 5.00 of the TomTom software.  There may be
+        some records that confuse the input module - if you have an example
+        of such a record "in the wild", and you aren't restricted from sharing
+        it, we encourage you to post to the gpsbabel-misc mailing list to 
+        contact a developer.
+
+        Note that in addition to the .ov2 file, you will need a .bmp file for
+        the icon.  It should be 22x22 and 16 colors, and have the same name
+        (not including the extension) as the .ov2 file.
 
 DATA FILTERS
 
@@ -745,6 +942,11 @@ DATA FILTERS
          41.144270897    -85.163655281
          41.141953468    -85.162882805
 
+        An arc file may optionally contain gaps in the arc.  You can 
+        specify such a gap by inserting a line containing "#break" 
+        either on a line by itself or after the coordinates of the
+        starting point of the new arc segment.
+
         In addition to the file containing the arc, you should also
         specify the maximum distance from the arc that will be accepted;
         that distance is declared on the command line with the
@@ -915,69 +1117,3 @@ DATA FILTERS
                     -x stack,pop,append \
                     -o magellan -F fwaind.wpt
  
-COMMON USAGE
-
-       Invocation was meant to be flexible.   Unfortunately, that can
-       sometimes lead to unwieldy command lines.
-
-               gpsbabel -? 
-
-       will always show you the supported file types.   To use this
-       program, just tell it what you're reading, where to read it from,
-       what you're writing, and what to write it to.  For example:
-
-       gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx
-
-       tells it to read the first file in geocaching.com format and create
-       a new file in GPX format.
-
-       This command will read from a Magellan unit attached to the first
-       serial port on a Linux system (device names will vary on other OSes)
-       and write them as a geocaching loc file.  The second command does 
-       the same for windows.
-
-       gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc
-       gpsbabel -i magellan -f com1 -o geo -F mag.loc
-       
-
-       Optionally, you may specify "-s" in any command line.  This causes
-       the program to ignore any "short" names that may be present in the
-       source data format and synthesize one from the long name.  This
-       is particularly useful if you're writing to a target format that 
-       isn't the lowest common denominator but the source data was written
-       for the lowest common denominator.   I use this for writing data
-       from geocaching.com to my Magellan so my waypoints have "real" names
-       instead of the 'GC1234' ones that are optimized for NMEA-only 
-       receivers.   A geocacher with a Magellan receiver may thus find
-       commands like this useful.
-
-       gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0 
-       gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1
-
-ADVANCED USAGE
-
-       Argument are processed in the order they appear on the command line.
-       Input is cumulative.  The input file type remains unchanged until a 
-       new -i argument is seen.  Files are read in the order they appear.  
-       So you could merge three input files into one output file with:
-       
-       gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc
-
-       You can merge files of different types:
-
-       gpsbabel  -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx -o gpsutil -F big.gps
-
-       You can write the same data in different output formats:
-
-       gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx 1.wpt
-
-ROUTE AND TRACK MODES
-
-        The presence of "-t" on the command line tells us to work with
-        tracks.  The presence of "-r" tells us to work with routes.
-        Tracks and routes are advanced features and don't try to
-        handle every possible hazard that can be encountered during a
-        conversion.  If you're merging or converting files of similar
-        limitations, things work very well.  The presence of "-s" on
-        the command line tends to creat havoc because tracks and routes.
-
diff --git a/an1.c b/an1.c
new file mode 100644 (file)
index 0000000..63035f4
--- /dev/null
+++ b/an1.c
@@ -0,0 +1,835 @@
+/*
+    Read DeLorme drawing files (.an1)
+    Copyright (C) 2005 Ron Parker and Robert Lipe.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#define MYNAME "an1"
+#include "defs.h"
+
+FILE *infile;
+FILE *outfile;
+
+static char *output_type = NULL;
+long output_type_num = 0;
+
+static long serial=10000;
+static long rtserial=1;
+
+static
+arglist_t an1_args[] = {
+       {"type", &output_type, "Type of .an1 file (0=drawing)", 
+               "0", ARGTYPE_HIDDEN | ARGTYPE_INT },
+       {0, 0, 0, 0 }
+};
+
+typedef struct guid {
+       unsigned long l;
+       unsigned short s[3];
+       unsigned char c[6];
+} GUID;
+
+#include "an1sym.h"
+
+static unsigned short
+ReadShort(FILE * f)
+{
+       gbuint16 result = 0;
+
+       fread(&result, sizeof (result), 1, f);
+       return le_read16(&result);
+}
+
+static void 
+WriteShort(FILE * f, unsigned short s)
+{
+       gbuint16 tmp = 0;
+        le_write16( &tmp, s );
+       fwrite( &tmp, sizeof(tmp), 1, f );
+}
+
+static unsigned long
+ReadLong(FILE * f)
+{
+       gbuint32 result = 0;
+
+       fread(&result, sizeof (result), 1, f);
+       return le_read32(&result);
+}
+
+static void 
+WriteLong(FILE * f, unsigned long l)
+{
+       gbuint32 tmp = 0;
+        le_write32( &tmp, l );
+       
+       fwrite( &tmp, sizeof(tmp), 1, f );
+}
+
+static double
+ReadDouble( FILE * f )
+{
+       double tmp = 0;
+       double result = 0;
+       fread(&tmp, sizeof(tmp),1,f);
+       le_read64(&result, &tmp );
+       return result;
+}
+
+static void 
+WriteDouble(FILE * f, double d)
+{
+       double tmp = 0;
+        le_read64( &tmp, (void *)&d );
+       fwrite( &tmp, sizeof(tmp), 1, f );
+}
+
+static char *
+ReadString( FILE * f, short len ) 
+{
+       char *result = NULL;
+       result = (char *)xcalloc( 1, len + 1 );
+       if ( len ) {
+               fread( result, 1, len, f );
+       }
+       return result;
+}
+
+static unsigned char
+ReadChar( FILE *f )
+{
+       unsigned char result = 0;
+       fread( &result, 1, 1, f );
+       return result;
+}
+
+static void
+WriteChar( FILE *f, unsigned char c ) 
+{
+       fwrite( &c, 1, 1, f );
+}
+
+static void
+WriteString( FILE *f, char *s )
+{
+       fwrite( s, 1, strlen(s), f );
+}
+
+static void 
+ReadGuid( FILE *f, GUID *guid )
+{
+       int i = 0;
+       guid->l = ReadLong( f );
+       for ( i = 0; i < 3; i++ ) {
+               guid->s[i] = ReadShort( f );
+       }
+       for ( i = 0; i < 6; i++ ) {
+               guid->c[i] = ReadChar( f );
+       }
+}
+
+static void 
+WriteGuid( FILE *f, GUID *guid )
+{
+       int i = 0;
+       WriteLong( f, guid->l );
+       for ( i = 0; i < 3; i++ ) {
+               WriteShort( f, guid->s[i] );
+       }
+       for ( i = 0; i < 6; i++ ) {
+               WriteChar( f, guid->c[i] );
+       }
+}      
+
+static void
+Skip(FILE * f,
+     unsigned long distance)
+{
+       fseek(f, distance, SEEK_CUR);
+}
+
+static double
+DecodeOrd( long ord )
+{
+       return (double)(0x80000000-ord)/(0x800000);
+}
+
+static long
+EncodeOrd( double ord )
+{
+       unsigned long tmp = ord * 0x800000;
+       return 0x80000000UL-tmp;
+}
+
+static int
+IsGuidEqual( GUID *a, GUID *b ) 
+{
+       return !memcmp( a, b, sizeof( GUID ));
+}
+
+typedef struct {
+       short hotspotxhi;
+       long hotspoty;
+       long unk1;
+       GUID guid;
+       char *name;
+} an1_symbol_record;
+
+typedef struct {
+       an1_base base;
+       short magic;
+       long unk1;
+       long lon;
+       long lat;
+       short type;
+       long height;
+       long width;
+       short unk2;
+       short unk3;
+       short serial;
+       short unk4;
+       unsigned char create_zoom;
+       unsigned char visible_zoom;
+       short unk5;
+       double radius;
+       char *name;
+       char *fontname;
+       GUID guid;
+       long fontcolor;
+       long fontstyle;
+       long fontsize;
+       long outlineweight;
+       long outlinecolor;
+       long outlineflags;
+       long fillcolor;
+       long unk6;
+       long fillflags;
+} an1_waypoint_record;
+
+typedef struct {
+       an1_base base;
+       short magic;
+       long unk0;
+       long lon;
+       long lat;
+       short unk1;
+} an1_vertex_record;
+
+typedef struct {
+       an1_base base;
+       short magic;
+       short unk1;
+       short serial;
+       long unk2;
+       short unk3;
+       short type;
+       long unk4;
+       char *name;
+       long lineweight;
+       long linestyle;
+       long linecolor;
+       long unk5;
+       long polyfillcolor;
+       long unk6;
+       long unk7;
+       short unk8;
+       long pointcount;
+} an1_line_record;
+
+static an1_waypoint_record *Alloc_AN1_Waypoint( );
+
+void Destroy_AN1_Waypoint( void *vwpt ) {
+       an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt;
+       xfree( wpt->name );
+       xfree( wpt->fontname );
+}
+
+void Copy_AN1_Waypoint( void **vdwpt, void *vwpt ) {
+       an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt;
+       an1_waypoint_record *dwpt = Alloc_AN1_Waypoint();
+       memcpy( dwpt, wpt, sizeof( an1_waypoint_record ));
+       dwpt->name = xstrdup( wpt->name );
+       dwpt->fontname = xstrdup( wpt->fontname );
+       *vdwpt = (void *)dwpt;
+}
+
+static an1_waypoint_record *Alloc_AN1_Waypoint( ) {
+       an1_waypoint_record *result = NULL;
+       result = (an1_waypoint_record *)xcalloc( sizeof(*result), 1 );
+       result->base.copy = Copy_AN1_Waypoint;
+       result->base.destroy = Destroy_AN1_Waypoint; 
+}
+       
+static an1_vertex_record *Alloc_AN1_Vertex();
+
+void Destroy_AN1_Vertex( void *vvertex ) {
+       /* do nothing */
+}
+
+void Copy_AN1_Vertex( void **vdvert, void *vvert ) {
+       an1_vertex_record *vert = (an1_vertex_record *)vvert;
+       an1_vertex_record *dvert = Alloc_AN1_Vertex();
+       memcpy( dvert, vert, sizeof( an1_vertex_record ));
+       *vdvert = (void *)dvert;
+}
+
+static an1_vertex_record *Alloc_AN1_Vertex() {
+       an1_vertex_record *result = NULL;
+       result = (an1_vertex_record *)xcalloc( sizeof( *result), 1 );
+       result->base.copy = Copy_AN1_Vertex;
+       result->base.destroy = Destroy_AN1_Vertex;
+}
+                       
+
+static an1_line_record *Alloc_AN1_Line();
+
+void Destroy_AN1_Line( void *vline ) {
+       an1_line_record *line = (an1_line_record *)vline;
+       xfree( line->name );
+}
+
+void Copy_AN1_Line( void **vdline, void *vline ) {
+       an1_line_record *line = (an1_line_record *)vline;
+       an1_line_record *dline = Alloc_AN1_Line();
+       memcpy( dline, line, sizeof( an1_line_record ));
+       dline->name = xstrdup( line->name );
+       *vdline = (void *)dline;
+}
+
+static an1_line_record *Alloc_AN1_Line( ) {
+       an1_line_record *result = NULL;
+       result = (an1_line_record *)xcalloc( sizeof(*result), 1 );
+       result->base.copy = Copy_AN1_Line;
+       result->base.destroy = Destroy_AN1_Line;
+}
+
+
+static void Destroy_AN1_Symbol( an1_symbol_record *symbol ) {
+       xfree( symbol->name );
+}
+
+static void Read_AN1_Waypoint( FILE *f, an1_waypoint_record *wpt ) {
+       short len;
+       
+       wpt->magic = ReadShort( f );
+       wpt->unk1 = ReadLong( f );
+       wpt->lon = ReadLong( f );
+       wpt->lat = ReadLong( f );
+       wpt->type = ReadShort( f );
+       wpt->height = ReadLong( f );
+       wpt->width = ReadLong( f );
+       wpt->unk2 = ReadShort( f );
+       wpt->unk3 = ReadShort( f );
+       wpt->serial = ReadShort( f );
+       wpt->unk4 = ReadShort( f );
+       wpt->create_zoom = ReadChar( f );
+       wpt->visible_zoom = ReadChar( f );
+       wpt->unk5 = ReadShort( f );
+       wpt->radius = ReadDouble( f );
+        len = ReadShort( f );
+        wpt->name = ReadString( f, len );
+        len = ReadShort( f );
+        wpt->fontname = ReadString( f, len );
+       ReadGuid( f, &wpt->guid );
+        wpt->fontcolor = ReadLong( f );
+       wpt->fontstyle = ReadLong( f );
+       wpt->fontsize = ReadLong( f );
+       wpt->outlineweight = ReadLong( f );
+       wpt->outlinecolor = ReadLong( f );
+       wpt->outlineflags = ReadLong( f );
+       wpt->fillcolor = ReadLong( f );
+       wpt->unk6 = ReadLong( f );
+       wpt->fillflags = ReadLong( f ); 
+}
+
+static void Write_AN1_Waypoint( FILE *f, an1_waypoint_record *wpt ) {
+       short len;
+       
+       WriteShort( f, wpt->magic );
+       WriteLong( f, wpt->unk1 );
+       WriteLong( f, wpt->lon );
+       WriteLong( f, wpt->lat );
+       WriteShort( f, wpt->type );
+       WriteLong( f, wpt->height );
+       WriteLong( f, wpt->width );
+       WriteShort( f, wpt->unk2 );
+       WriteShort( f, wpt->unk3 );
+       WriteShort( f, wpt->serial );
+       WriteShort( f, wpt->unk4 );
+       WriteChar( f, wpt->create_zoom );
+       WriteChar( f, wpt->visible_zoom );
+       WriteShort( f, wpt->unk5 );
+       WriteDouble( f, wpt->radius );
+       len = strlen( wpt->name );
+       WriteShort( f, len );
+        WriteString( f, wpt->name );
+       len = strlen( wpt->fontname );
+       WriteShort( f, len );
+        WriteString( f, wpt->fontname );
+       WriteGuid( f, &wpt->guid );
+        WriteLong( f, wpt->fontcolor );
+       WriteLong( f, wpt->fontstyle );
+       WriteLong( f, wpt->fontsize );
+       WriteLong( f, wpt->outlineweight );
+       WriteLong( f, wpt->outlinecolor );
+       WriteLong( f, wpt->outlineflags );
+       WriteLong( f, wpt->fillcolor );
+       WriteLong( f, wpt->unk6 );
+       WriteLong( f, wpt->fillflags ); 
+}
+
+static void Read_AN1_Vertex( FILE *f, an1_vertex_record *vertex ) {
+       
+       vertex->magic = ReadShort( f );
+       vertex->unk0 = ReadLong( f );
+       vertex->lon = ReadLong( f );
+       vertex->lat = ReadLong( f );
+       vertex->unk1 = ReadShort( f );
+}
+
+static void Write_AN1_Vertex( FILE *f, an1_vertex_record *vertex ) {
+       WriteShort( f, vertex->magic );
+       WriteLong( f, vertex->unk0 );
+       WriteLong( f, vertex->lon );
+       WriteLong( f, vertex->lat );
+       WriteShort( f, vertex->unk1 );
+}
+
+static void Read_AN1_Line( FILE *f, an1_line_record *line ) {
+       
+       short len;
+       
+       line->magic = ReadShort( f );
+       line->unk1 = ReadShort( f );
+       line->serial = ReadShort( f );
+       line->unk2 = ReadLong( f );
+       line->unk3 = ReadShort( f );
+       line->type = ReadShort( f );
+       line->unk4 = ReadLong( f );
+       len = ReadShort( f );
+       line->name = ReadString( f, len );
+       line->lineweight = ReadShort( f );
+       line->linestyle = ReadLong( f );
+       line->linecolor = ReadLong( f );
+       line->unk5 = ReadLong( f );
+       line->polyfillcolor = ReadLong( f );
+       line->unk6 = ReadLong( f );
+       line->unk7 = ReadLong( f );
+       line->unk8 = ReadShort( f );
+       line->pointcount = ReadLong( f );
+}
+
+static void Write_AN1_Line( FILE *f, an1_line_record *line ) {
+       short len;
+       
+       WriteShort( f, line->magic );
+       WriteShort( f, line->unk1 );
+       WriteShort( f, line->serial );
+       WriteLong( f, line->unk2 );
+       WriteShort( f, line->unk3 );
+       WriteShort( f, line->type );
+       WriteLong( f, line->unk4 );
+       len = strlen( line->name );
+       WriteShort( f, len );
+       WriteString( f, line->name );
+       WriteShort( f, line->lineweight );
+       WriteLong( f, line->linestyle );
+       WriteLong( f, line->linecolor );
+       WriteLong( f, line->unk5 );
+       WriteLong( f, line->polyfillcolor );
+       WriteLong( f, line->unk6 );
+       WriteLong( f, line->unk7 );
+       WriteShort( f, line->unk8 );
+       WriteLong( f, line->pointcount );
+} 
+
+static void Skip_AN1_IL( FILE *f ) {
+       Skip( f, 26 );
+}
+
+static void Skip_AN1_BM( FILE *f ) {
+       unsigned long bmsize;
+       unsigned long palettesize;
+       unsigned long bmisize;
+       unsigned long bitoffset;
+       
+       Skip( f, 8 );  /* BITMAPFILEHEADER fields 1-3 */
+       bitoffset = ReadLong( f );
+       
+       bmisize = ReadLong( f );
+       Skip( f, 16 );  /* BITMAPINFOHEADER fields 2-6 */
+       bmsize = ReadLong( f );
+       Skip( f, 16 );  /* BITMAPINFOHEADER fields 8-11 */
+       
+       palettesize = bitoffset - bmisize - 14;
+       Skip( f, bmsize + palettesize );
+}
+
+static void Read_AN1_Symbol( FILE *f, an1_symbol_record *symbol ) {
+       short len;
+
+       /* This is just the high word of a long; we ate the low 
+        * word in the caller.  Fortunately, we don't care. */
+       symbol->hotspotxhi = ReadShort( f );
+       symbol->hotspoty = ReadLong( f );
+       symbol->unk1 = ReadLong( f );
+       ReadGuid( f, &symbol->guid );
+       len = ReadChar( f );
+       symbol->name = ReadString( f, len );
+}
+
+static void Read_AN1_Header( FILE *f ) {
+       unsigned short magic;
+       unsigned short type;
+       
+       magic = ReadShort( f );
+       type = ReadShort( f );
+}
+
+static void Write_AN1_Header( FILE *f ) {
+       WriteShort( f, 11557 );
+       WriteShort( f, atoi( output_type ) );
+}
+
+static void Read_AN1_Bitmaps( FILE *f ) {
+       long count;
+       unsigned short magic;
+       an1_symbol_record symbol;
+       
+       count = ReadLong( f );
+       
+       while ( count ) {
+               magic = ReadShort( f );
+               switch (magic) {
+                       case 0x4d42:
+                               Skip_AN1_BM( f );
+                               break;
+                       case 0x4c49:
+                               Skip_AN1_IL( f );
+                               break;
+                       default:
+                               Read_AN1_Symbol( f, &symbol );
+                               Destroy_AN1_Symbol( &symbol );
+                               count--;
+                               break;
+               }
+       }
+                                               
+       /* Read the symbol table */
+}
+
+static void Write_AN1_Bitmaps( FILE *f ) {
+       /* On write, we don't output any bitmaps, so writing them
+        * is just a matter of writing a count of zero */
+       WriteLong( f, 0 );
+}
+
+static void Read_AN1_Waypoints( FILE *f ) {
+       unsigned long count = 0;
+       unsigned long i = 0;
+       an1_waypoint_record *rec = NULL;
+       waypoint *wpt_tmp;
+       char *icon = NULL;
+       ReadShort( f );
+       count = ReadLong( f );
+       for (i = 0; i < count; i++ ) {
+               rec = Alloc_AN1_Waypoint();
+               Read_AN1_Waypoint( f, rec );
+               wpt_tmp = waypt_new();
+               
+               wpt_tmp->longitude = -DecodeOrd( rec->lon );
+               wpt_tmp->latitude = DecodeOrd( rec->lat );
+               wpt_tmp->description = xstrdup( rec->name );
+               
+               if (FindIconByGuid(&rec->guid, &icon)) {
+                       wpt_tmp->icon_descr = icon;
+               }
+               
+               wpt_tmp->an1_extras = (an1_base *)(void *)rec;
+               rec = NULL;
+               waypt_add( wpt_tmp );
+       }
+}
+
+static void
+Write_One_AN1_Waypoint( const waypoint *wpt )
+{
+       an1_waypoint_record *rec;
+       int local;
+       
+       if ( wpt->an1_extras ) {
+               rec = (an1_waypoint_record *)(void *)(wpt->an1_extras); 
+               xfree( rec->name );
+               local = 0;
+       }
+       else {
+               rec = Alloc_AN1_Waypoint();
+               local = 1;
+               rec->magic = 1;
+               rec->type = 1;
+               rec->unk2 = 3;
+               rec->unk3 = 18561;
+               rec->fontname = xstrdup( "Arial" );
+               FindIconByName( "Red Flag", &rec->guid );
+               rec->fontsize = 10;
+       }
+       rec->name = xstrdup( wpt->description );
+       rec->lat = EncodeOrd( wpt->latitude );
+       rec->lon = EncodeOrd( -wpt->longitude );
+       rec->serial = serial++;
+       
+       if ( wpt->icon_descr ) {
+               FindIconByName( (char *)(void *)wpt->icon_descr, &rec->guid );
+       }
+       
+       Write_AN1_Waypoint( outfile, rec );
+       if ( local ) {
+               Destroy_AN1_Waypoint( rec );
+               xfree( rec );
+       }
+}
+
+static void Write_AN1_Waypoints( FILE *f ) {
+       WriteShort( f, 2 );
+       WriteLong( f, waypt_count() );
+       waypt_disp_all( Write_One_AN1_Waypoint );
+}
+
+static void Read_AN1_Lines( FILE *f ) {
+       unsigned long count = 0;
+       unsigned long i = 0;
+       unsigned long j = 0;
+       an1_line_record *rec = NULL;
+       an1_vertex_record *vert = NULL;
+        route_head *rte_head;
+        waypoint *wpt_tmp;
+
+       ReadShort( f );
+       count = ReadLong( f );
+       for (i = 0; i < count; i++ ) {
+               rec = Alloc_AN1_Line();
+               Read_AN1_Line( f, rec );
+               /* create route rec */
+                rte_head = route_head_alloc();
+               rte_head->an1_extras = (an1_base *)(void *)rec;
+                route_add_head(rte_head);
+               for (j = 0; j < rec->pointcount; j++ ) {
+                       vert = Alloc_AN1_Vertex();
+                       Read_AN1_Vertex( f, vert );
+                       
+                       /* create route point */
+                       wpt_tmp = waypt_new();
+                        wpt_tmp->latitude = DecodeOrd( vert->lat );
+                       wpt_tmp->longitude = -DecodeOrd( vert->lon );
+                       wpt_tmp->shortname = (char *) xmalloc(7);
+                       sprintf( wpt_tmp->shortname, "\\%5.5x", rtserial++ );
+                       wpt_tmp->an1_extras = (an1_base *)(void *)vert;
+                       route_add_wpt(rte_head, wpt_tmp);
+               }
+       }
+}
+
+static void
+Write_One_AN1_Line( const route_head *rte )
+{
+       an1_line_record *rec;
+       int local;
+       
+       if ( rte->an1_extras ) {
+               rec = (an1_line_record *)(void *)(rte->an1_extras);     
+               local = 0;
+               switch (output_type_num) {
+                       case 1:
+                               if ( rec->type != 14 ) {
+                                       rec = Alloc_AN1_Line();
+                                       memcpy( rec, rte->an1_extras, sizeof(an1_line_record));
+                                       local = 1;
+                                       rec->magic = 4112;
+                                       rec->unk1 = 4359;
+                                       rec->unk2 = 655360;
+                                       rec->type = 14;
+                                       rec->unk8 = 2;
+                               } // end if
+                               break;
+                       case 2:
+                               if ( rec->type != 15 ) {
+                                       rec = Alloc_AN1_Line();
+                                       memcpy( rec, rte->an1_extras, sizeof(an1_line_record));
+                                       local = 1;
+                                       rec->type = 15;
+                               } // end if
+                               break;                          
+                       case 4:
+                               if ( rec->type != 16 ) {
+                                       rec = Alloc_AN1_Line();
+                                       memcpy( rec, rte->an1_extras, sizeof(an1_line_record));
+                                       local = 1;
+                                       rec->type = 16;
+                               } // end if
+                               break;
+               }
+       }
+       else {
+               rec = Alloc_AN1_Line();
+               local = 1;
+               switch (output_type_num) {
+                       /*  drawing road trail waypoint track  */
+                       case 1: /* road */
+                               rec->magic = 4112;
+                               rec->unk1 = 4359;
+                               rec->unk2 = 655360;
+                               rec->type = 14;
+                               rec->unk8 = 2;
+                               break;
+                               
+                       case 2: /* trail */
+                               rec->magic = 7248;
+                               rec->unk1 = 4359;
+                               rec->unk2 = 917504;
+                               rec->type = 15;
+                               rec->unk8 = 2;
+                               break;
+                               
+                       case 4: /* track */
+                               rec->magic = 21;
+                               rec->unk1 = 18560;
+                               rec->unk2 = 917504;
+                               rec->type = 16;
+                               rec->unk4 = 2;
+                               rec->unk8 = 2;
+                               break;
+                               
+                       case 0: /* drawing */
+                       case 3: /* waypoint - shouldn't have lines */
+                       default:
+                               rec->magic = 21;
+                               rec->unk1 = 18560;
+                               rec->unk2 = 1048576;
+                               rec->type = 2;
+                               rec->unk4 = 2;
+                               rec->lineweight = 6;
+                               rec->linecolor = 255; /* red */
+                               rec->unk5 = 3;
+                               rec->unk8 = 2;
+                               break;
+               }
+               rec->name = xstrdup( "" );
+                               
+       }
+       rec->serial = serial++;
+       rec->pointcount = rte->rte_waypt_ct;    
+       Write_AN1_Line( outfile, rec );
+       if ( local ) {
+               Destroy_AN1_Line( rec );
+               xfree( rec );
+       }
+}
+
+static void
+Write_One_AN1_Vertex( const waypoint *wpt )
+{
+       an1_vertex_record *rec;
+       int local;
+       
+       if ( wpt->an1_extras ) {
+               rec = (an1_vertex_record *)(void *)(wpt->an1_extras);   
+               local = 0;
+       }
+       else {
+               rec = Alloc_AN1_Vertex();
+               local = 1;
+               rec->magic = 1;
+       }
+       rec->lat = EncodeOrd( wpt->latitude );
+       rec->lon = EncodeOrd( -wpt->longitude );
+       
+       Write_AN1_Vertex( outfile, rec );
+       if ( local ) {
+               Destroy_AN1_Vertex( rec );
+               xfree( rec );
+       }
+}
+
+static void Write_AN1_Lines( FILE *f ) {
+       WriteShort( f, 2 );
+       WriteLong( f, route_count()+track_count() );
+       
+       route_disp_all( Write_One_AN1_Line, NULL, Write_One_AN1_Vertex );
+       track_disp_all( Write_One_AN1_Line, NULL, Write_One_AN1_Vertex );
+}
+
+static void
+rd_init(const char *fname)
+{
+       infile = xfopen(fname, "rb", MYNAME);
+       output_type_num = atoi( output_type );
+}
+
+static void
+rd_deinit(void)
+{
+       fclose(infile);
+}
+
+static void
+my_read(void)
+{
+       Read_AN1_Header( infile );
+       Read_AN1_Bitmaps( infile );
+       Read_AN1_Waypoints( infile );
+       Read_AN1_Lines( infile );
+}
+
+static void
+wr_init(const char *fname)
+{
+       outfile = xfopen( fname, "wb", MYNAME );
+       output_type_num = atoi( output_type );
+}
+
+static void
+wr_deinit( void ) 
+{
+       fclose(outfile);
+}
+
+static void
+my_write( void ) 
+{
+       Write_AN1_Header( outfile );
+       Write_AN1_Bitmaps( outfile );
+       Write_AN1_Waypoints( outfile );
+       Write_AN1_Lines( outfile );
+}
+
+ff_vecs_t an1_vecs = {
+       ff_type_file,
+       FF_CAP_RW_ALL,
+       rd_init,
+       wr_init,
+       rd_deinit,
+       wr_deinit,
+       my_read,
+       my_write,
+       NULL, 
+       an1_args
+};
diff --git a/an1sym.h b/an1sym.h
new file mode 100644 (file)
index 0000000..8c5f0b4
--- /dev/null
+++ b/an1sym.h
@@ -0,0 +1,519 @@
+/* 
+
+
+
+
+
+
+
+
+
+                       THIS FILE IS AUTOMATICALLY GENERATED
+
+
+                       Please change make-an1sym.pl and
+                       regenerate it rather than changing
+                       this file directly.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+*/
+
+/*
+    Read DeLorme drawing files (.an1) - supplemental (included by an1.c)
+    Copyright (C) 2005 Ron Parker and Robert Lipe.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+struct defguid {
+       GUID guid;
+       char *name;
+} default_guids[] = {
+  {{0xb610bc70,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Hiker"},
+  {{0xb610bc71,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Canoe"},
+  {{0xb610bc72,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Kayak"},
+  {{0xb610bc73,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Bike"},
+  {{0xb610bc74,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Four wheeler"},
+  {{0xb610bc75,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Jeep"},
+  {{0xb610bc76,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Snowmobile"},
+  {{0xb610bc78,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Rec Vehicle"},
+  {{0xb610bc79,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Fire"},
+  {{0xb610bc7a,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Fishing"},
+  {{0xb610bc7b,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Tree"},
+  {{0xb610bc7c,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Pine Tree"},
+  {{0xb610bc7d,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Birch"},
+  {{0xb610bc7e,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Deer"},
+  {{0xb610bc7f,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Moose"},
+  {{0x99d8c163,{0x7622, 0x11d5, 0xe8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Mud"},
+  {{0x012dfac2,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Tractor"},
+  {{0x012dfac3,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Combine Harvester"},
+  {{0x012dfac7,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Front-End Loader"},
+  {{0xfd163780,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Power Shovel"},
+  {{0xfd163781,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Road Grader"},
+  {{0xfd163784,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Road Roller"},
+  {{0xfd163787,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dump Truck"},
+  {{0x5673d712,{0xb28d, 0x11d5, 0x13b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Skid-Steer Loader"},
+  {{0xb86045ac,{0x390f, 0x420f, 0x91a7}, {0x76, 0x2f, 0x48, 0xea, 0xe2, 0xd7}},
+            "Highway Sign"},
+  {{0x1e129e95,{0x13b6, 0x48d8, 0x3fa3}, {0x9c, 0xc8, 0x20, 0x8e, 0x1d, 0x9d}},
+            "Orange Cone"},
+  {{0xadee7d54,{0xf7c9, 0x4ab6, 0xfb93}, {0x99, 0xc3, 0xbc, 0x9d, 0x15, 0x47}},
+            "Barricade"},
+  {{0xa170000f,{0x8bd8, 0x4574, 0x58ac}, {0x55, 0x41, 0x67, 0xef, 0x64, 0x62}},
+            "Flagger"},
+  {{0xa425f90e,{0x6ab6, 0x4ca9, 0x8997}, {0xbf, 0xca, 0xe0, 0xc2, 0x2b, 0x53}},
+            "Construction Sign"},
+  {{0x0805b240,{0x6b26, 0x4300, 0xebb1}, {0xea, 0x9b, 0xcf, 0x68, 0xc6, 0x18}},
+            "Construction Flasher"},
+  {{0x56721a6c,{0x8e77, 0x4b62, 0x09aa}, {0xce, 0xdc, 0x69, 0x4a, 0x16, 0x05}},
+            "Transit"},
+  {{0x623e1ee9,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Arrow Left"},
+  {{0x623e1eea,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Arrow Right"},
+  {{0x623e1eeb,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Arrow Up"},
+  {{0x623e1eec,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Arrow Down"},
+  {{0x623e1eed,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Arrow Up Left"},
+  {{0x623e1eee,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Arrow Up Right"},
+  {{0x623e1eef,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Arrow Down Left"},
+  {{0x623e1ef0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Arrow Down Right"},
+  {{0x83f91421,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Arrow Left"},
+  {{0x83f91422,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Arrow Right"},
+  {{0x83f91423,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Arrow Up"},
+  {{0x83f91424,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Arrow Down"},
+  {{0x83f91425,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Arrow Up Left"},
+  {{0x83f91426,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Arrow Up Right"},
+  {{0x83f91427,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Arrow Down Left"},
+  {{0x83f91428,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Arrow Down Right"},
+  {{0x83f91429,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Large Arrow Left"},
+  {{0x83f9142a,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Large Arrow Right"},
+  {{0x83f9142b,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Large Arrow Up"},
+  {{0x83f9142c,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Large Arrow Down"},
+  {{0x83f9142d,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Large Arrow Down Right"},
+  {{0x83f9142e,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Large Arrow Down Left"},
+  {{0x83f9142f,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Large Arrow Up Left"},
+  {{0x83f91430,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Large Arrow Up Right"},
+  {{0x8ff0aad1,{0xc53d, 0x4998, 0x7ebd}, {0x06, 0x60, 0x25, 0x6c, 0x4f, 0x6d}},
+            "Accommodation"},
+  {{0xaf7bf199,{0x6a8b, 0x49fe, 0xae92}, {0xa3, 0x09, 0x7b, 0xb8, 0x81, 0x6a}},
+            "Australia"},
+  {{0x6bbcc9d1,{0x6a19, 0x4c7b, 0xc6a2}, {0x3e, 0x17, 0x02, 0xd6, 0xee, 0x3a}},
+            "Blue Dome Cross"},
+  {{0xfff920fe,{0xd780, 0x49d4, 0x1bad}, {0x55, 0x2e, 0xc7, 0xdf, 0xa2, 0xaa}},
+            "Green Dome Cross"},
+  {{0x57e75924,{0xd6fa, 0x4666, 0x84bf}, {0x5b, 0x76, 0xa1, 0xd0, 0x14, 0x5f}},
+            "Business"},
+  {{0xb09ef4a7,{0x95e4, 0x4e5e, 0x5e84}, {0xbe, 0x2b, 0x86, 0xdd, 0x50, 0x65}},
+            "Airplane"},
+  {{0xf2833c22,{0x3592, 0x4a8a, 0x5693}, {0xee, 0x6c, 0x83, 0xb6, 0x3c, 0x19}},
+            "Amusement Recreation"},
+  {{0x6f0317d6,{0x7fa3, 0x4dcc, 0x6187}, {0x7e, 0xca, 0xcb, 0x65, 0x49, 0x12}},
+            "Green Square"},
+  {{0x18a6d3c0,{0x45cb, 0x4d19, 0xf5b9}, {0xc7, 0x9c, 0xbf, 0x8f, 0x6d, 0x46}},
+            "Red Triangle"},
+  {{0x86e68ea7,{0xb9ab, 0x4bc8, 0xa1bf}, {0xc1, 0x22, 0x13, 0x97, 0x95, 0xe8}},
+            "Red Triangle and Green Square"},
+  {{0x6afd74bf,{0x0ea5, 0x4680, 0xcd88}, {0x15, 0x87, 0x2f, 0x6c, 0xd2, 0xd8}},
+            "City 4"},
+  {{0x49dfeb74,{0xbb09, 0x4df1, 0x5687}, {0xd8, 0xa0, 0xff, 0x36, 0x89, 0x3d}},
+            "White Square"},
+  {{0x3eed62c6,{0xdab9, 0x42b0, 0xe4a3}, {0xd2, 0xf1, 0x7d, 0x54, 0xbf, 0x77}},
+            "White Triangle"},
+  {{0x6b521940,{0x4492, 0x4c48, 0x58a0}, {0xfc, 0xd1, 0x1f, 0x5e, 0x0c, 0xea}},
+            "Red Black Diamond Flag"},
+  {{0xbb8ebaa3,{0xac59, 0x4411, 0x9c94}, {0x30, 0xd4, 0xe1, 0x21, 0x25, 0x46}},
+            "Yellow Diamond Flag"},
+  {{0x8e118862,{0xf6aa, 0x4b34, 0x2b82}, {0x8f, 0x3b, 0x5a, 0x2b, 0x59, 0xeb}},
+            "Small Pink Square"},
+  {{0xd0ef64c2,{0xe319, 0x4876, 0x1b85}, {0x0e, 0x90, 0x50, 0x89, 0xb7, 0xc5}},
+            "Store"},
+  {{0xa22b08fb,{0x6193, 0x4f5c, 0xdaa4}, {0xfa, 0xdf, 0xa7, 0x6e, 0x23, 0xe1}},
+            "Camping"},
+  {{0x27f57c69,{0x575b, 0x4b56, 0x288c}, {0xe8, 0xe1, 0xc7, 0x05, 0x1f, 0x1f}},
+            "Green Diamond Flag"},
+  {{0xe07abb38,{0x219f, 0x4b52, 0x868b}, {0x45, 0x0f, 0xbc, 0xc1, 0x4f, 0x6a}},
+            "Red Diamond Flag"},
+  {{0x3a124ac9,{0x3973, 0x4e27, 0x4b82}, {0xa6, 0x3a, 0x94, 0x5c, 0xf8, 0xb3}},
+            "Red Green Diamond Flag"},
+  {{0x64ed669b,{0x0db8, 0x4ec9, 0xd181}, {0x98, 0x50, 0xb3, 0x8b, 0x2f, 0x2e}},
+            "White Globe"},
+  {{0x3cb10adc,{0xb090, 0x4960, 0x9f8a}, {0xec, 0xaf, 0x6c, 0xd7, 0xaa, 0x8b}},
+            "Yellow Globe"},
+  {{0x2779347d,{0x17d4, 0x4021, 0xa6a8}, {0x51, 0x9a, 0xb6, 0xf8, 0x21, 0xff}},
+            ""},
+  {{0x3ad63f7b,{0x4339, 0x427d, 0x5797}, {0xce, 0xa9, 0x96, 0x33, 0x8b, 0x3c}},
+            "Black Cross"},
+  {{0x3e89481e,{0x35ff, 0x48b6, 0xc7ae}, {0xb0, 0x75, 0xf6, 0x43, 0xc4, 0xc7}},
+            "Church"},
+  {{0x68622c10,{0x79b6, 0x466d, 0xa8a3}, {0x27, 0xc6, 0x25, 0x34, 0xfa, 0xa9}},
+            "Small Dark Green Square"},
+  {{0x42c6a873,{0x2d0c, 0x46e7, 0x9989}, {0xdd, 0x86, 0x01, 0x6e, 0xa4, 0xc9}},
+            "Small Black Square"},
+  {{0x50e3b06e,{0xbe81, 0x4b2c, 0x1f92}, {0x80, 0xa5, 0x72, 0x9b, 0x33, 0x05}},
+            "Danger"},
+  {{0x369d0b22,{0xed07, 0x421f, 0x8780}, {0x33, 0x0e, 0xbd, 0x27, 0x4f, 0x3c}},
+            "Construction Business"},
+  {{0x10603b6c,{0xb02e, 0x49ee, 0x60b9}, {0xed, 0x7e, 0x31, 0x16, 0x27, 0x89}},
+            "Airport"},
+  {{0x8328aab7,{0xfe04, 0x46dc, 0x7bbf}, {0x29, 0x34, 0x30, 0xd3, 0x4d, 0xeb}},
+            "City 5"},
+  {{0x96411287,{0xda33, 0x40e3, 0xaa9c}, {0x75, 0x83, 0x78, 0x2d, 0xa6, 0xf3}},
+            "USA"},
+  {{0xb2f98627,{0x1211, 0x40e8, 0xb287}, {0x6d, 0x66, 0xfd, 0x15, 0x1e, 0xd4}},
+            "Diver Down"},
+  {{0x3fce26d0,{0xfec6, 0x4f8b, 0x55a2}, {0x89, 0x3a, 0x8e, 0x59, 0x08, 0x0a}},
+            "Light Yellow Square"},
+  {{0xb4b68597,{0x1aed, 0x4918, 0xd492}, {0x1f, 0xd1, 0x5e, 0xf2, 0x55, 0xc1}},
+            "Education Technology"},
+  {{0x35d2e6a8,{0xda88, 0x4edb, 0x4b80}, {0x2b, 0x1b, 0xcf, 0xc0, 0xd4, 0x6d}},
+            "Computer"},
+  {{0x4ddc4e96,{0x8d19, 0x4079, 0x4488}, {0xc0, 0x8f, 0x0f, 0x8e, 0xb5, 0xd7}},
+            "Amusement Recreation Red"},
+  {{0x79f58929,{0x46c6, 0x4337, 0xc0b1}, {0xf0, 0x09, 0x55, 0xbb, 0x1f, 0xc3}},
+            "Telephone Red"},
+  {{0x0083b377,{0xfb80, 0x4a83, 0x3593}, {0x56, 0xe5, 0xfe, 0xc4, 0xcd, 0x43}},
+            "Exit"},
+  {{0x0c232891,{0xab4d, 0x440e, 0x7083}, {0x05, 0x63, 0x3a, 0xf5, 0x66, 0x11}},
+            "Exit with Services"},
+  {{0xaf63e7c2,{0x03fa, 0x418e, 0xc68b}, {0x02, 0xb8, 0xf5, 0x61, 0xb6, 0x61}},
+            "Pizza"},
+  {{0xd419c693,{0x39e6, 0x43db, 0xa1b8}, {0x7f, 0xcc, 0x2c, 0xb8, 0x51, 0x4a}},
+            "Financial Services"},
+  {{0x70740a81,{0xe4ca, 0x4ac2, 0xa498}, {0x21, 0xc8, 0x5b, 0xc0, 0xb7, 0xae}},
+            "City 3"},
+  {{0x9a582ff6,{0x34c4, 0x41c6, 0xf0a3}, {0x99, 0x69, 0x9d, 0xbe, 0x2e, 0x08}},
+            "Food Store"},
+  {{0x3cd31689,{0x2f8f, 0x4fb0, 0xcb88}, {0x34, 0x84, 0xfc, 0x8b, 0x03, 0xe4}},
+            ""},
+  {{0x952557a6,{0xe29e, 0x4512, 0x1184}, {0x1a, 0x3c, 0x9c, 0xd4, 0x83, 0x7d}},
+            ""},
+  {{0x03dc278c,{0xe8ff, 0x46ac, 0x3daa}, {0x9f, 0xe9, 0x1e, 0xcf, 0x10, 0x35}},
+            "Driving Range"},
+  {{0xacd28bab,{0x0ec0, 0x4393, 0xaf8b}, {0xbb, 0x5e, 0x74, 0xb3, 0x87, 0x12}},
+            "Golf Municipal"},
+  {{0x984e7139,{0xeab8, 0x49f6, 0x55a0}, {0x8d, 0x51, 0xe6, 0xdd, 0xcc, 0xf4}},
+            "Golf Private"},
+  {{0xec5828ab,{0x2a9d, 0x48f8, 0xd79b}, {0xc9, 0xc3, 0x30, 0x8e, 0xe4, 0xea}},
+            "Golf Public"},
+  {{0xb0120d99,{0x683a, 0x4ecc, 0x129a}, {0x29, 0x94, 0x1f, 0x04, 0xae, 0x10}},
+            "Golf Resort"},
+  {{0x2ce7685a,{0x6eaf, 0x4061, 0x29a5}, {0x87, 0x5e, 0xfa, 0x41, 0x75, 0x1a}},
+            "Golf Semi Private"},
+  {{0x10397049,{0x9fc9, 0x4380, 0x5680}, {0x81, 0xd9, 0xe7, 0x43, 0x1f, 0x11}},
+            "Medical Service"},
+  {{0x2fc28df6,{0xe806, 0x436e, 0xe0b9}, {0x46, 0x1d, 0xeb, 0xad, 0x56, 0x60}},
+            "Home Furnishings"},
+  {{0x910313db,{0xafce, 0x4019, 0x1aa4}, {0xe6, 0x2c, 0xe6, 0xd1, 0xfd, 0xf7}},
+            "Industrial"},
+  {{0x9e442c6e,{0xe12a, 0x4407, 0xd68a}, {0x1c, 0x5e, 0x19, 0xe7, 0xfe, 0x01}},
+            ""},
+  {{0x37e2fe4a,{0xcd71, 0x413f, 0x0cad}, {0x81, 0xc5, 0x2c, 0xf4, 0x78, 0x79}},
+            ""},
+  {{0x3c756e09,{0xb2dc, 0x48a6, 0x04a9}, {0x20, 0xb7, 0xc9, 0x9d, 0x14, 0x51}},
+            ""},
+  {{0xa1245b1c,{0x156a, 0x48fc, 0x6f96}, {0xa5, 0xa3, 0x22, 0x54, 0x13, 0x97}},
+            "Manufacturing"},
+  {{0x5bddbd7a,{0xf3cb, 0x454c, 0x06af}, {0x46, 0x1a, 0x68, 0xea, 0x60, 0x1a}},
+            "Note"},
+  {{0xcb6777e1,{0xe0e0, 0x45ce, 0x309f}, {0x8d, 0x61, 0x7a, 0xd9, 0x89, 0xf5}},
+            "City"},
+  {{0xbc168c08,{0x2b7f, 0x44be, 0x3883}, {0x81, 0x31, 0x4a, 0x09, 0xf5, 0x78}},
+            "Air Base"},
+  {{0xa8857b0f,{0xfc3b, 0x4cd1, 0x9e91}, {0xf5, 0x3b, 0x21, 0xa8, 0x3b, 0xb9}},
+            "Battlefield"},
+  {{0x06db55c1,{0xf687, 0x4840, 0x7c80}, {0x95, 0x58, 0x77, 0x8e, 0x5a, 0xdd}},
+            "Mining"},
+  {{0xcc61b277,{0xa48c, 0x445a, 0xd9b9}, {0xe5, 0x91, 0x36, 0x18, 0x4e, 0x09}},
+            "Mountain"},
+  {{0xfde13186,{0xb6cb, 0x4374, 0xc880}, {0x56, 0x99, 0xeb, 0x51, 0x68, 0x87}},
+            "Capital"},
+  {{0xb14d90d1,{0xd943, 0x40ff, 0x9fb7}, {0x9b, 0x92, 0xd1, 0x23, 0xca, 0xef}},
+            "Route"},
+  {{0x7eabc63f,{0x05d0, 0x4465, 0xb1b0}, {0x61, 0x2a, 0xf7, 0x4d, 0x0f, 0x4e}},
+            "Overnight"},
+  {{0xac39d8b9,{0xfcdc, 0x4b50, 0x9ca6}, {0xea, 0x6c, 0x4b, 0xb5, 0x96, 0x0f}},
+            "Route End Active"},
+  {{0xe1b9d86b,{0x95e6, 0x4bd8, 0xd880}, {0x7b, 0x6c, 0xc6, 0xd2, 0x00, 0x34}},
+            "Route End Inactive"},
+  {{0x98712315,{0x7e1e, 0x4024, 0x8392}, {0xe3, 0xb8, 0x5a, 0x51, 0x45, 0xb4}},
+            "Fuel Stop"},
+  {{0xe5ea5b38,{0x7b80, 0x4b42, 0x0aba}, {0x3d, 0x38, 0xf0, 0xe1, 0x17, 0x9a}},
+            "Route Start Active"},
+  {{0x18fd0d49,{0x0a29, 0x433a, 0xd584}, {0xe5, 0xb7, 0x5b, 0xe8, 0x25, 0xbc}},
+            "Route Start Inactive"},
+  {{0x2f52144b,{0x903e, 0x4dd9, 0x79af}, {0xe1, 0x66, 0x9b, 0xfc, 0xa9, 0xc1}},
+            "Route Stop Active"},
+  {{0xfaf8d826,{0xd27d, 0x4316, 0x0e92}, {0xce, 0x8d, 0x85, 0x93, 0x4c, 0xf5}},
+            "Route Stop Inactive"},
+  {{0xff44cae2,{0x707c, 0x4a1c, 0x43af}, {0x8b, 0xb6, 0xb1, 0x19, 0x9c, 0xf2}},
+            "Route Via"},
+  {{0x5a50d59b,{0xc15b, 0x49c4, 0x9faa}, {0xc4, 0x1c, 0x4f, 0xe2, 0x95, 0x2a}},
+            "Radiation Green"},
+  {{0x19556023,{0xb1e5, 0x4c9c, 0x49ba}, {0x08, 0x52, 0xa1, 0x24, 0x3d, 0x9f}},
+            "Radiation Red"},
+  {{0xa54be251,{0x6688, 0x49fb, 0x60b3}, {0x89, 0x56, 0x37, 0x68, 0xc5, 0xb0}},
+            "Electricity"},
+  {{0xd793ff0c,{0xfbe0, 0x4383, 0x3183}, {0xcf, 0x4f, 0x04, 0xb7, 0xee, 0x0a}},
+            "Personal Furnishings"},
+  {{0x00f90733,{0x7ab5, 0x42cf, 0x468c}, {0xbf, 0x91, 0x27, 0xd3, 0xa8, 0x9c}},
+            "Personal Services"},
+  {{0xea677f24,{0xbbe8, 0x4238, 0xee9c}, {0x6c, 0x0a, 0xec, 0x0e, 0x34, 0xf4}},
+            "Telephone Black"},
+  {{0x2d8a05b5,{0x8baf, 0x4f28, 0xf58b}, {0xfb, 0x7f, 0x37, 0x34, 0x28, 0xa7}},
+            "Government Light"},
+  {{0x40c64dfc,{0xc2d0, 0x4b0e, 0x6582}, {0x3f, 0x26, 0x9c, 0xcb, 0x6f, 0x1d}},
+            "Airport Red Square"},
+  {{0xf27adb5d,{0x3629, 0x44c7, 0x95a2}, {0x25, 0x2c, 0x95, 0x24, 0x98, 0x2f}},
+            "Propeller Aircraft"},
+  {{0x5a718e13,{0x3547, 0x42c5, 0x6d9d}, {0xb2, 0x82, 0xa5, 0x53, 0xbd, 0x3a}},
+            "Jet Aircraft"},
+  {{0x0a471039,{0x2dfe, 0x447e, 0x54be}, {0xa3, 0x93, 0xae, 0x9a, 0xdd, 0xac}},
+            "Government"},
+  {{0x4a59da2f,{0xe1c3, 0x42c3, 0x6ca1}, {0x06, 0xb9, 0x14, 0x1b, 0x89, 0x99}},
+            "USA Regional"},
+  {{0xf16500a9,{0xa845, 0x4293, 0xae89}, {0x5c, 0x29, 0xbb, 0x0d, 0x06, 0xf7}},
+            "House 2"},
+  {{0x7b05524d,{0xcb5a, 0x456f, 0x96b3}, {0x03, 0x61, 0x24, 0x54, 0x6a, 0x54}},
+            "Picnic"},
+  {{0xb88ad7a1,{0xb94d, 0x42e8, 0x2b9d}, {0xf5, 0x4c, 0x2b, 0xff, 0x57, 0xdc}},
+            "Restaurant"},
+  {{0xdc48a20a,{0x54a2, 0x4c61, 0x1fbe}, {0x02, 0x74, 0x5b, 0xe9, 0x18, 0x99}},
+            "Store 2"},
+  {{0x6b5ab040,{0x96df, 0x46ae, 0xacb8}, {0xe4, 0x47, 0x66, 0x3f, 0xec, 0x9b}},
+            ""},
+  {{0x153b2cff,{0x6232, 0x4294, 0xd59a}, {0xc5, 0xa0, 0x7b, 0xe0, 0x16, 0xeb}},
+            "Blue Star"},
+  {{0xf276f6b3,{0x586a, 0x4bf8, 0x2f82}, {0xf2, 0x69, 0xe3, 0x76, 0x7e, 0xd5}},
+            ""},
+  {{0x91d242c8,{0x0986, 0x4fad, 0x8286}, {0xec, 0x79, 0x79, 0xcd, 0xab, 0x02}},
+            "Running"},
+  {{0x8b0078db,{0x6ee0, 0x4caa, 0xd3b5}, {0xfe, 0xe1, 0xc2, 0xbf, 0x94, 0x7d}},
+            "Transportation"},
+  {{0x0599f6c9,{0x478e, 0x4f63, 0x78a5}, {0xed, 0x31, 0xb5, 0xae, 0xda, 0x89}},
+            "Fishing"},
+  {{0x7389128c,{0x0e78, 0x4d5d, 0x4189}, {0xb8, 0xf3, 0xb5, 0xbd, 0x70, 0xb1}},
+            "Automotive"},
+  {{0x0362b593,{0x3df6, 0x48ed, 0xc489}, {0x85, 0x13, 0xc1, 0xc0, 0xb9, 0x0d}},
+            "Cloudy"},
+  {{0xf0717a94,{0xd048, 0x4770, 0x9bab}, {0x80, 0x09, 0xbd, 0x4b, 0x1e, 0x75}},
+            "Partly Cloudy"},
+  {{0x14486bbc,{0xae6b, 0x44ea, 0xd6b9}, {0xbf, 0x9a, 0x39, 0x7a, 0x51, 0x6c}},
+            "Mostly Cloudy"},
+  {{0x7a258c70,{0xabec, 0x4cff, 0x4983}, {0x84, 0xdc, 0x2f, 0x2e, 0xff, 0x28}},
+            "Tornado"},
+  {{0xeff260d4,{0x46d5, 0x4fb5, 0xc79c}, {0x5e, 0x06, 0xc8, 0xab, 0x7a, 0x2b}},
+            "Lightning"},
+  {{0xc3d70220,{0x5154, 0x4766, 0xf0af}, {0xdf, 0x86, 0x74, 0x40, 0x5f, 0x8c}},
+            "Rain"},
+  {{0xf2dfbc91,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Blue Flag"},
+  {{0xf2dfbc92,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dark Blue Flag"},
+  {{0xf2dfbc93,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Brown Flag"},
+  {{0xf2dfbc94,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Yellow Flag"},
+  {{0xf2dfbc95,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Red Flag 2"},
+  {{0xf2dfbc96,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dark Red Flag"},
+  {{0xf2dfbc97,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dark Green Flag"},
+  {{0xf2dfbc98,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Green Flag"},
+  {{0xf2dfbc99,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Blue-Green Flag"},
+  {{0xf2dfbc9a,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Light Blue Flag"},
+  {{0x623e1ee1,{0xaf27, 0x100f, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Dark Blue Map Pin"},
+  {{0xf2dfbc9d,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Blue Map Pin"},
+  {{0xf2dfbc9e,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Yellow Map Pin"},
+  {{0xf2dfbc9f,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Brown Map Pin"},
+  {{0xf2dfbca0,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Red Map Pin"},
+  {{0xf2dfbca1,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dark Red Map Pin"},
+  {{0xf2dfbca2,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Green Map Pin"},
+  {{0xf2dfbca3,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dark Green Map Pin"},
+  {{0xf2dfbca4,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Gray Map Pin"},
+  {{0xf2dfbca5,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dark Gray Map Pin"},
+  {{0xd1703de0,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Green Dot"},
+  {{0xd1703de1,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dark Green Dot"},
+  {{0xd1703de2,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Blue Dot"},
+  {{0xd1703de3,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dark Blue Dot"},
+  {{0xd1703de5,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Red Dot"},
+  {{0x45c088e0,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Dark Red Dot"},
+  {{0x45c088e1,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Yellow Dot"},
+  {{0x45c088e2,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Brown Dot"},
+  {{0x45c088e3,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Light Blue Dot"},
+  {{0xbde3a8a1,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Blue-Green Dot"},
+  {{0xbde3a8a2,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Green Dot"},
+  {{0xbde3a8a3,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Dark Green Dot"},
+  {{0xbde3a8a4,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Blue Dot"},
+  {{0xbde3a8a5,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Dark Blue Dot"},
+  {{0xbde3a8a6,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Red Dot"},
+  {{0xbde3a8a7,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Dark Red Dot"},
+  {{0xbde3a8a8,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Yellow Dot"},
+  {{0xbde3a8a9,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Brown Dot"},
+  {{0xbde3a8aa,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Light Blue Dot"},
+  {{0xbde3a8ab,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}},
+            "Small Blue-Green Dot"},
+  {{0x623e1ee0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Red Flag"},
+  {{0x623e1ee1,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Map Pin"},
+  {{0x623e1ee2,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Yellow Square"},
+  {{0x623e1ee3,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Red X"},
+  {{0x623e1ee4,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Blue Circle"},
+  {{0x623e1ee5,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "House"},
+  {{0x623e1ee7,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Triangle"},
+  {{0x623e1ee8,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}},
+            "Green Star"},
+  {{0x9d277805,{0xe2f8, 0x4f43, 0x3f97}, {0x35, 0x0d, 0x40, 0xae, 0x5c, 0xd3}},
+            "Geocache"},
+  {{0xcb8aad04,{0xcc2d, 0x47f2, 0x428a}, {0x80, 0xf7, 0xd6, 0x68, 0xed, 0x32}},
+            "Geocache Found"},
+  {{0x7341c1f4,{0xdecd, 0x4d35, 0x45a5}, {0x52, 0x25, 0x5e, 0xbf, 0xe6, 0x51}},
+            "Tent"},
+  {{0x835b84e2,{0xf10c, 0x45cb, 0x958f}, {0x18, 0x3a, 0xc2, 0x2a, 0xe5, 0x28}},
+            "Tipup Up"},
+  {{0xce06fc92,{0xbb0c, 0x4ec1, 0xda93}, {0x64, 0x4a, 0x60, 0xbe, 0x40, 0x90}},
+            "Topup Down"},
+};
+
+int FindIconByName( const char *name, GUID *guid ) {
+       int i = 0; 
+       for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ )
+       {
+               if ( !case_ignore_strcmp(name, default_guids[i].name)) {
+                       memcpy( guid, &(default_guids[i].guid), sizeof(GUID));
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+int FindIconByGuid( GUID *guid, char **name ) {
+       int i = 0; 
+       for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ )
+       {
+               if ( !memcmp(guid, &default_guids[i].guid, sizeof(GUID))) {
+                       *name = default_guids[i].name;
+                       return 1;
+               }
+       }
+       return 0;
+}
index 3fc13459a29d9c61816cd528c3e1c48c9e80875d..800c45dd424487b5af04b55d7757d53e407d7c97 100644 (file)
--- a/arcdist.c
+++ b/arcdist.c
@@ -74,7 +74,12 @@ arcdist_process(void)
            fileline++;
            
            pound = strchr( line, '#' );
-           if ( pound ) *pound = '\0';
+           if ( pound ) {
+               if ( 0 == strncmp( pound, "#break", 6)) {
+                   lat1 = lon1 = BADVAL;
+               }
+               *pound = '\0';
+           }
            
            lat2 = lon2 = BADVAL;
            argsfound = sscanf( line, "%lf %lf", &lat2, &lon2 );
index 2d06c5753e2cc81d33d13a2f99a34001d138a734..e42d820c24af938527b72e6af0b12f0219281a21 100644 (file)
@@ -268,6 +268,7 @@ static arglist_t brauniger_iq_args[] = {
 
 ff_vecs_t brauniger_iq_vecs = {
     ff_type_serial,
+    FF_CAP_RW_ALL,
     rd_init,
     NULL,
     rd_deinit,
diff --git a/cetus.c b/cetus.c
index a85c9d4877ca4e37c6eb5ead1d8277b2f2579b4e..6b09650d0a9a3381dd3e17ceab4ea42fa751eef5 100644 (file)
--- a/cetus.c
+++ b/cetus.c
@@ -60,7 +60,7 @@ struct record {
        unsigned char sec;
        
        /* accuracy and precision information for use where applicable */
-       char  sat; /* ff if averaged or unknown */
+       unsigned char  sat; /* ff if averaged or unknown */
        pdb_16 pdop; /* pdop * 100 */
        pdb_16 hdop;
        pdb_16 vdop;
@@ -165,7 +165,7 @@ data_read(void)
        for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) {
                waypoint *wpt_tmp;
 
-               wpt_tmp = xcalloc(sizeof(*wpt_tmp),1);
+               wpt_tmp = waypt_new();
 
                rec = (struct record *) pdb_rec->data;
                if ( be_read32(&rec->elevation) == -100000000 ) {
@@ -238,13 +238,13 @@ cetus_writewpt(const waypoint *wpt)
                be_write16(&rec->year, 0xff);
        }
 
-       be_write32(&rec->longitude, wpt->longitude * 10000000.0);
-       be_write32(&rec->latitude, wpt->latitude * 10000000.0);
+       be_write32(&rec->longitude, (unsigned int) (wpt->longitude * 10000000.0));
+       be_write32(&rec->latitude, (unsigned int) (wpt->latitude * 10000000.0));
        if ( wpt->altitude == unknown_alt ) {
-               be_write32(&rec->elevation, -100000000U);
+               be_write32(&rec->elevation, -100000000);
        }
        else {
-               be_write32(&rec->elevation, wpt->altitude * 100.0);
+               be_write32(&rec->elevation, (unsigned int) (wpt->altitude * 100.0));
        }
        
        be_write16( &rec->pdop, 0xffff );
@@ -327,7 +327,7 @@ cetus_writewpt(const waypoint *wpt)
        }
        vdata += strlen( vdata ) + 1;
        
-       opdb_rec = new_Record (0, 2, ct++, vdata-(char *)rec, (const ubyte *)rec);
+       opdb_rec = new_Record (0, 2, ct++, (uword) (vdata-(char *)rec), (const ubyte *)rec);
        
        if (opdb_rec == NULL) {
                fatal(MYNAME ": libpdb couldn't create record\n");
@@ -397,7 +397,7 @@ data_write(void)
            if (global_opts.synthesize_shortnames && waypointp->description) {
                if (waypointp->shortname)
                    xfree(waypointp->shortname);
-               waypointp->shortname = mkshort(mkshort_wr_handle, waypointp->description);
+               waypointp->shortname = mkshort_from_wpt(mkshort_wr_handle, waypointp);
            }
            bh->wpt_name = waypointp->shortname;
            bh ++;
@@ -416,6 +416,7 @@ data_write(void)
 
 ff_vecs_t cetus_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
diff --git a/chkdoc b/chkdoc
index b3a409b706d2e197b6a349586378bdc7992712a8..19f93ed136f9ec2f48b1efe9422e8913a3739616 100644 (file)
--- a/chkdoc
+++ b/chkdoc
@@ -16,11 +16,12 @@ checkit() {
                ECODE=1
        fi
        
-       if ! grep -qi "^    $TYPE$" README 
+       if ! grep -qi "^    $TYPE$" ~/src/babelweb/README 
        then
                echo $STY $TYPE is not documented in README.
                ECODE=1
        fi
+
 }
 
 ./gpsbabel -^ |
@@ -39,5 +40,25 @@ do
        checkit $TYPE filter
 done
 
+#
+# See if they're in testo.
+#
+./gpsbabel -^2 | 
+while read FMT
+do
+       set -- $FMT
+       case $1 in
+       file) 
+       TYPE=$3
+       if ! grep -qi "$TYPE" testo
+       then
+               echo $STY $TYPE is not in testo.
+               ECODE=1
+       fi
+
+       esac
+done
+
+
 
 exit $ECODE
diff --git a/coastexp.c b/coastexp.c
new file mode 100644 (file)
index 0000000..faef555
--- /dev/null
@@ -0,0 +1,637 @@
+/*
+    Copyright (C) 2004 Justin Broughton, justinbr@earthlink.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#if !NO_EXPAT
+#include "xmlgeneric.h"
+#include <expat.h>
+static XML_Parser psr;
+#endif
+#include <time.h>
+
+#include "uuid.h"
+
+FILE *fd;
+FILE *ofd;
+
+#define MYNAME "coastexp"
+#define MY_CBUF 4096
+#define MY_UBUF 128
+#define MY_TBUF 64
+#define MY_XBUF 128
+
+#if NO_EXPAT
+void
+ce_rd_init(const char *fname)
+{
+       fatal(MYNAME ": This build excluded CoastalExplorer support because expat was not installed.\n");
+}
+
+void
+ce_read(void)
+{
+}
+#else
+
+static char *element; // Current element being parsed
+static char *cdatastr; // Current XML character data being built up (until a <lf>)
+
+/* CE-specific mark structure - used for both route marks and standalone marks */
+struct CE_MARK {
+       queue Q;
+       char *id;               // CE's mark ID (of the form "{<guid>}")
+       char *created;  // CE's creation time (of the form "<YYYY><MM><DD>T<HH><MM><SS>Z")
+       waypoint *wp;   // GPSBabel waypoint
+       int used;               // Is this mark used in a route or not?
+};
+typedef struct CE_MARK ce_mark;
+
+/* CE-specific route structure */
+struct CE_ROUTE {
+       queue Q;
+       char *id;                       // CE's route ID (of the form "{<guid>}")
+       route_head *r;          // GPSBabel route header
+       queue ce_mark_head;     // list of CE marks in this route
+};
+typedef struct CE_ROUTE ce_route;
+
+static queue ce_route_head;                            // List of routes currently found
+static ce_route *currentRoute = NULL;  // Current route being processed
+static queue ce_mark_head;                             // List of stand-alone marks currently found
+static ce_mark *currentMark = NULL;            // Current mark being processed
+static char *time_buffer = NULL;               // Time buffer for processing times
+static char *uuid_buffer = NULL;               // UUID buffer for processing uuid's
+static char *xml_buffer = NULL;                        // XML buffer for processing XML strings
+static int inRoute = 0;                                        // Are we processing a route?
+static int inMark = 0;                                 // Are we processing a mark?
+
+/* Add a route to the list of routes */
+static void
+ce_add_route(ce_route *route)
+{
+       ENQUEUE_TAIL(&ce_route_head, &route->Q);
+}
+
+/* Add a mark to the list of stand-alone marks */
+static void
+ce_add_mark(ce_mark *mark)
+{
+       ENQUEUE_TAIL(&ce_mark_head, &mark->Q);
+}
+
+/* Add a mark to the specified route */
+static void
+ce_add_mark_to_route(ce_route *route, ce_mark *mark)
+{
+       ENQUEUE_TAIL(&route->ce_mark_head, &mark->Q);
+}
+
+/* Free a mark */
+static void
+ce_free_mark(ce_mark *mark)
+{
+       xfree(mark->id);
+       if (mark->created)
+               xfree(mark->created);
+       xfree(mark);
+}
+
+/* Free a route */
+static void
+ce_free_route(ce_route *route)
+{
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&route->ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
+               ce_free_mark(mark);
+       }
+       xfree(route->id);
+       xfree(route);
+       // Don't free the waypoint since this is done elsewhere
+}
+
+/* Start processing an XML item */
+static void
+ce_start(void *data, const char *el, const char **attr)
+{
+       const char **ap;
+       strcpy(element, el);
+       if (0 == strcmp(el, "Route")) {
+               inRoute = 1;
+               for (ap = attr; *ap; ap+=2) {
+                       if (0 == strcmp(ap[0], "id")) {
+                               // Create a CE route object and add it to the list of routes
+                               currentRoute = (ce_route *) xcalloc(sizeof (ce_route), 1);
+                               currentRoute->id=xstrdup(ap[1]);
+                               if (doing_rtes) 
+                                       currentRoute->r = route_head_alloc();
+                               QUEUE_INIT(&currentRoute->ce_mark_head);
+                               if (doing_rtes) 
+                                       ce_add_route(currentRoute);
+                       }
+               }
+       } else if (0 == strcmp(el, "Mark")) {
+               inMark = 1;
+               currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1);
+               currentMark->wp = NULL;
+               currentMark->used = 0;
+               ce_add_mark(currentMark);
+               for (ap = attr; *ap; ap+=2) {
+                       if (0 == strcmp(ap[0], "id")) {
+                               // Create a CE mark object and add it to the list of stand-alone marks
+                               currentMark->id = xstrdup(ap[1]);
+                       }
+                       else if (0 == strcmp(ap[0], "created")) {
+                               currentMark->created = xstrdup(ap[1]);
+                       }
+               }
+       }
+}
+
+/* Finish processing an XML item */
+static void
+ce_end(void *data, const char *el)
+{
+       if (0 == strcmp(el, "Route")) {
+               if (!doing_rtes)
+                       ce_free_route(currentRoute);
+               inRoute = 0;
+       }
+       else if (0 == strcmp(el, "Mark"))
+               inMark = 0;
+}
+
+/* Process some XML character data for the current item */
+static void
+ce_cdata(void *dta, const XML_Char *s, int len)
+{
+       if (*s != '\n') {
+               char *edatastr;
+               // We buffer up characters in 'cdatastr' until a single <lf> is received
+               if ((strlen(cdatastr) + len) > MY_CBUF) {
+                       printf("Buffer overflow - line too long!");
+                       exit(-1);
+               }
+               edatastr = cdatastr+strlen(cdatastr);
+               memcpy(edatastr, s, len);
+               edatastr[len] = '\0';
+       } else {
+               // Now process what we have in 'cdatastr'
+               s = cdatastr;
+               while (*s != '\0' && (*s == '\b' || *s == '\t'))
+                       s++;
+               if (strlen(s) <= 0)
+                       return;
+               if (0 == strcmp(element, "Marks")) {
+                       if (inRoute) {
+                               // We are processing the marks in a route so create a CE mark object
+                               // and add it to the current route
+                               ce_mark *mark = (ce_mark *) xcalloc(sizeof (ce_mark), 1);
+                               mark->id = xstrdup(s);
+                               mark->created = NULL;
+                               mark->wp = NULL;
+                               ce_add_mark_to_route(currentRoute, mark);
+                       }
+               } else if (0 == strcmp(element, "Position")) {
+                       if (inMark) {
+                               // We are processing a standalone mark so read the lat/long position
+                               // and create a waypoint to add to the current mark
+                               char *position = xstrdup(s);
+                               char *lat = position;
+                               char *latNorS = position;
+                               char *lng;
+                               char *longEorW;
+                               while (*latNorS != ' ')
+                                       latNorS++;
+                               *latNorS++ = '\0';
+                               lng = latNorS;
+                               lng++; lng++;
+                               longEorW = lng;
+                               while (*longEorW != ' ')
+                                       longEorW++;
+                               *longEorW++ = '\0';
+                               if (!currentMark->wp)
+                                       currentMark->wp = waypt_new();
+                               currentMark->wp->latitude = atof(lat);
+                               if (*latNorS == 'S')
+                                       currentMark->wp->latitude = -currentMark->wp->latitude;
+                               currentMark->wp->longitude = atof(lng);
+                               if (*longEorW == 'W')
+                                       currentMark->wp->longitude = -currentMark->wp->longitude;
+                               xfree(position);
+                       }
+               } else if (0 == strcmp(element, "Name")) {
+                       // Names we care about may be either for routes or marks
+                       if (inMark)
+                       {
+                               if (!currentMark->wp)
+                                       currentMark->wp = waypt_new();
+                               currentMark->wp->shortname = xstrdup(s);
+
+                               // Also set the creation time
+                               if (currentMark->created)
+                               {
+                                       struct tm t;
+                                       char yearString[5], monthString[3], dayString[3], hourString[3], minString[3], secString[3];
+                                       memset(&t, 0, sizeof(struct tm));
+                                       strncpy(yearString, currentMark->created, 4);
+                                       yearString[4] = '\0';
+                                       t.tm_year = atoi(yearString) - 1900;
+                                       strncpy(monthString, currentMark->created+4, 2);
+                                       monthString[2] = '\0';
+                                       t.tm_mon = atoi(monthString) - 1;
+                                       strncpy(dayString, currentMark->created+6, 2);
+                                       dayString[2] = '\0';
+                                       t.tm_mday = atoi(dayString);
+                                       strncpy(hourString, currentMark->created+9, 2);
+                                       hourString[2] = '\0';
+                                       t.tm_hour = atoi(hourString);
+                                       strncpy(minString, currentMark->created+11, 2);
+                                       minString[2] = '\0';
+                                       t.tm_min = atoi(minString);
+                                       strncpy(secString, currentMark->created+13, 2);
+                                       secString[2] = '\0';
+                                       t.tm_sec = atoi(secString);
+                                       currentMark->wp->creation_time = mktime(&t) + get_tz_offset();
+                               }
+                       }
+                       else if (inRoute) {
+                               if (doing_rtes)
+                               currentRoute->r->rte_name = xstrdup(s);
+                       }
+               } else if (0 == strcmp(element, "Description")) {
+                       // Descriptions we care about may be either for routes or marks
+                       char *desc = xstrdup(s);
+                       if (inMark)
+                       {
+                               if (!currentMark->wp)
+                                       currentMark->wp = waypt_new();
+                               currentMark->wp->description = desc;
+                       }
+                       else if (inRoute)
+                               currentRoute->r->rte_desc = desc;
+               }
+
+               // Start building a new string since we are done with this one
+               cdatastr[0] = '\0';
+       }
+}
+
+/* Set up reading the CE input file */
+void
+ce_rd_init(const char *fname)
+{
+       fd = xfopen(fname, "r", MYNAME);
+       QUEUE_INIT(&ce_route_head);
+       QUEUE_INIT(&ce_mark_head);
+
+       psr = XML_ParserCreate(NULL);
+       if (!psr) {
+               fatal(MYNAME ":Cannot create XML parser\n");
+       }
+
+       XML_SetElementHandler(psr, ce_start, ce_end);
+       cdatastr = xcalloc(MY_CBUF,1);
+       element = xcalloc(MY_CBUF,1);
+       XML_SetCharacterDataHandler(psr, ce_cdata);
+}
+
+/* Parse the input file */
+void
+ce_read(void)
+{
+       int len;
+       char buf[MY_CBUF];
+
+       while ((len = fread(buf, 1, sizeof(buf), fd))) {
+               if (!XML_Parse(psr, buf, len, feof(fd))) {
+                       fatal(MYNAME ":Parse error at %d: %s\n",
+                               XML_GetCurrentLineNumber(psr),
+                               XML_ErrorString(XML_GetErrorCode(psr)));
+               }
+       }
+
+       XML_ParserFree(psr);
+}
+
+#endif
+
+/* Fix waypoints in route marks from the standalone marks */
+void
+ce_fix_route_mark_waypoints(void)
+{
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_route_head, elem, tmp) {
+               ce_route *route = (ce_route *) elem;
+               queue *elem2, *tmp2;
+               QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) {
+                       ce_mark *mark = (ce_mark *) elem2;
+                       queue *elem3, *tmp3;
+                       QUEUE_FOR_EACH(&ce_mark_head, elem3, tmp3) {
+                               ce_mark *mark2 = (ce_mark *) elem3;
+                               if (0 == strcmp(mark->id, mark2->id)) {
+                                       mark->wp = waypt_dupe(mark2->wp);
+                                       mark2->used = 1;
+                                       break;
+                               }
+                       }
+               }
+       }
+}
+
+/* Check route name and if NULL assign a name */
+void
+ce_check_route_names(void)
+{
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_route_head, elem, tmp) {
+               ce_route *route = (ce_route *) elem;
+               if (route->r->rte_name == NULL) {
+                       *cdatastr = '\0';
+                       strcat(cdatastr, ((ce_mark *) QUEUE_FIRST(&route->ce_mark_head))->wp->shortname);
+                       strcat(cdatastr, "->");
+                       strcat(cdatastr, ((ce_mark *) QUEUE_LAST(&route->ce_mark_head))->wp->shortname);
+                       route->r->rte_name = xstrdup(cdatastr);
+               }
+       }
+}
+
+/* Remove marks used in routes */
+void
+ce_remove_used_marks(void)
+{
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
+               if (mark->used)
+               {
+                       dequeue(elem);
+                       if (mark->wp)
+                               waypt_free(mark->wp);
+                       ce_free_mark(mark);
+               }
+       }
+}
+
+/* Print out results */
+void
+ce_print_results(void)
+{
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_route_head, elem, tmp) {
+               queue *elem2, *tmp2;
+               ce_route *route = (ce_route *) elem;
+               printf("Route name=%s id=%s\n", route->r->rte_name, route->id);
+               QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) {
+                       ce_mark *mark = (ce_mark *) elem2;
+                       if (mark->wp == NULL)
+                               printf("  null\n");
+                       else
+                               printf("  %s (%f, %f)\n", mark->wp->shortname, mark->wp->latitude, mark->wp->longitude);
+               }
+       }
+
+       QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
+               printf("Mark name=%s id=%s ", mark->wp->shortname, mark->id);
+               if (mark->wp == NULL)
+                       printf("(null)\n");
+               else
+                       printf("(%f, %f)\n", mark->wp->latitude, mark->wp->longitude);
+       }
+}
+
+/* Finish reading the input file */
+void
+ce_rd_deinit(void)
+{
+       /* If doing routes, we create GPSBabel route structures and waypoint structures for
+          any standalone waypoints.
+          If doing waypoints, we create only waypoint structures for both route waypoints and
+          standalone waypoints.
+       */
+       queue *elem, *tmp;
+
+       if (doing_rtes) {
+               ce_fix_route_mark_waypoints();
+       ce_check_route_names();
+               ce_remove_used_marks();
+       }
+
+       // Log results
+       if (global_opts.debug_level > 1)
+               ce_print_results();
+
+       // Add routes to GPSBabel
+       QUEUE_FOR_EACH(&ce_route_head, elem, tmp) {
+               ce_route *route = (ce_route *) elem;
+               if (doing_rtes) {
+               queue *elem2, *tmp2;
+               route_add_head(route->r);
+               QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) {
+                       ce_mark *mark = (ce_mark *) elem2;
+                       if (mark->wp)
+                               route_add_wpt(route->r, mark->wp);
+                       else
+                               printf("Undefined mark: %s\n", mark->id);
+               }
+               }
+               ce_free_route(route);
+       }
+
+       // Add (unused) marks to GPSBabel
+       QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
+               waypt_add(mark->wp);
+               ce_free_mark(mark);
+       }
+
+       fclose(fd);
+       xfree(element);
+       xfree(cdatastr);
+}
+
+/* Setup for writing */
+void
+ce_wr_init(const char *fname)
+{
+       QUEUE_INIT(&ce_mark_head);
+
+       // Alloocate all buffers used for writing
+       time_buffer = xcalloc(MY_TBUF,1);
+       uuid_buffer = xcalloc(MY_UBUF,1);
+       xml_buffer = xcalloc(MY_XBUF, 1);
+
+       ofd = xfopen(fname, "w", MYNAME);
+}
+
+void
+ce_wr_deinit(void)
+{
+       fclose(ofd);
+
+       // Free the buffers used for writing
+       xfree(time_buffer);
+       xfree(uuid_buffer);
+       xfree(xml_buffer);
+}
+
+/* Generate a CE-style creation time based on supplied time */
+static char *
+ce_gen_creation_time(time_t tm)
+{
+       xml_fill_in_time(time_buffer, tm, XML_SHORT_TIME);
+       return time_buffer;
+}
+
+/* Generate a CE-style creation time based on current time */
+static char *
+ce_gen_current_time(void)
+{
+       return ce_gen_creation_time(current_time());
+}
+
+/* Generate a UUID (has same format as Microsoft registry GUIDs */
+static char *
+ce_gen_uuid(void)
+{
+       uuid_t uu;
+       uuid_generate(uu);
+       sprintf(uuid_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+               uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7],
+               uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
+       return uuid_buffer;
+}
+
+/* Generate route header XML */
+static void
+ce_route_hdr(const route_head *rte)
+{
+       if (doing_rtes) {
+               sprintf(xml_buffer, "{%s}", ce_gen_uuid());
+               write_xml_entity_begin2(ofd, "\t", "Route", "created", ce_gen_current_time(), "id", xml_buffer);
+               write_xml_entity_begin0(ofd, "\t\t", "Marks");
+       }
+}
+
+/* Generate route body XML */
+static void
+ce_route_disp(const waypoint *waypointp)
+{
+       char *uuid = ce_gen_uuid();
+       char *id = xcalloc(strlen(uuid)+3, 1);
+       sprintf(id, "{%s}", uuid);
+       currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1);
+       currentMark->id = id;
+       currentMark->wp = (waypoint *) waypointp;
+       ENQUEUE_TAIL(&ce_mark_head, &currentMark->Q);
+       fprintf(ofd, "\t\t\t%s\n", id); // CE's departure from XML standard!
+}
+
+/* Generate route trailer XML */
+static void
+ce_route_tlr(const route_head *rte)
+{
+       if (doing_rtes) {
+               write_xml_entity_end(ofd, "\t\t", "Marks");
+               write_optional_xml_entity(ofd, "\t\t", "Name", rte->rte_name);
+               write_xml_entity_end(ofd, "\t", "Route");
+       }
+}
+
+/* Generate waypoint body XML */
+static void
+ce_waypt_pr(const waypoint *wp)
+{
+       double latitude = wp->latitude;
+               char NorS = 'N';
+               char EorW = 'E';
+       double longitude = wp->longitude;
+
+               if (latitude < 0) {
+                       latitude = -latitude;
+                       NorS = 'S';
+               }
+               if (longitude < 0) {
+                       longitude = -longitude;
+                       EorW = 'W';
+               }
+       sprintf(xml_buffer, "%3.6f %c %3.6f %c", latitude, NorS, longitude, EorW);
+       write_xml_entity(ofd, "\t\t", "Position", xml_buffer);
+       write_optional_xml_entity(ofd, "\t\t", "Name", wp->shortname);
+}
+
+/* Generate a standalone mark XML */
+static void
+ce_mark_pr(const waypoint *wp)
+{
+       write_xml_entity_begin2(ofd, "\t", "Mark",
+                                                       "created", ce_gen_creation_time(wp->creation_time),
+                                                       "id", ce_gen_uuid());
+       ce_waypt_pr(wp);
+       write_xml_entity_end(ofd, "\t", "Mark");
+}
+
+/* Generate all route marks */
+static void
+ce_marks_pr(void)
+{
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
+               ce_mark_pr(mark->wp);
+               ce_free_mark(mark);
+       }
+}
+
+/* Write all routes and marks */
+void
+ce_write(void)
+{
+       /* If doing routes, we write out the routes and all the standalone waypoints.
+          If doing waypoints, we write out the route waypoints (without the routes) and
+          the standalone waypoints.
+       */
+       time_t now = 0;
+       now = current_time();
+
+       write_xml_header(ofd);
+       write_xml_entity_begin1(ofd, "", "NavObjectCollection", "created",
+                                                  ce_gen_current_time());
+       write_xml_entity(ofd, "\t", "Name", "Navigation Objects");
+
+       route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp);
+       ce_marks_pr();
+       waypt_disp_all(ce_mark_pr);
+
+       write_xml_entity_end(ofd, "", "NavObjectCollection");
+}
+
+ff_vecs_t coastexp_vecs = {
+       ff_type_file,
+       { ff_cap_read|ff_cap_write, ff_cap_none, ff_cap_read|ff_cap_write },
+       ce_rd_init,
+       ce_wr_init,
+       ce_rd_deinit,
+       ce_wr_deinit,
+       ce_read,
+       ce_write,
+       NULL,
+       NULL,
+};
index d923e57f9fb45f7b9ca222d1dffac1d4bbce557e..041b7f12c258ff28b830c9cea629094709d88897 100644 (file)
@@ -6,7 +6,7 @@
  *     You may distribute this file under the terms of the Artistic
  *     License, as specified in the README file.
  *
- * $Id: pdb.c,v 1.6 2004/04/16 16:47:51 parkrrrr Exp $
+ * $Id: pdb.c,v 1.7 2005/03/18 03:56:35 robertl Exp $
  */
 /* XXX - The way zero-length records are handled is a bit of a kludge. They
  * shouldn't normally exist, with the exception of expunged records. But,
@@ -33,7 +33,9 @@
  * but doesn't have it prototyped.  Systems with 64-bit file I/O but
  * based on LP64 model (i.e. OS/X) _require_ the prototype for lseek.
  */
-#if !defined (__WIN32__)
+#if defined (__WIN32__)
+#include <io.h>
+#else
 #include <unistd.h>
 #endif
 #include <stdlib.h>
@@ -434,7 +436,7 @@ pdb_Write(const struct pdb *db,
        wptr = header_buf;
        memcpy(wptr, db->name, PDB_DBNAMELEN);
        wptr += PDB_DBNAMELEN;
-       put_uword(&wptr, (db->attributes & ~PDB_ATTR_OPEN));
+       put_uword(&wptr, (uword) (db->attributes & ~PDB_ATTR_OPEN));
                                /* Clear the 'open' flag before writing */
        put_uword(&wptr, db->version);
        put_udword(&wptr, db->ctime);
@@ -1200,7 +1202,7 @@ get_file_length(int fd)
        /* And return to where we were before */
        lseek(fd, here, SEEK_SET);
 
-       return eof - here;
+       return (uword) (eof - here);
 }
 
 /* pdb_LoadHeader
@@ -1519,9 +1521,9 @@ pdb_LoadAppBlock(int fd,
                 struct pdb *db)
 {
        int err;
-       localID next_off;               /* Offset of the next thing in the file
+       udword next_off;                /* Offset of the next thing in the file
                                 * after the AppInfo block */
-       off_t offset;           /* Offset into file, for checking */
+       udword offset;          /* Offset into file, for checking */
 
        /* Check to see if there even *is* an AppInfo block */
        if (db->appinfo_offset == 0L)
@@ -1582,7 +1584,7 @@ pdb_LoadAppBlock(int fd,
         * we've already passed the beginning of the AppInfo block, as
         * given by its offset in the header.
         */
-       offset = lseek(fd, 0L, SEEK_CUR);       /* Find out where we are */
+       offset = (udword) lseek(fd, 0L, SEEK_CUR);      /* Find out where we are */
        if (offset != db->appinfo_offset)
        {
                if (offset > db->appinfo_offset)
@@ -1638,7 +1640,7 @@ pdb_LoadSortBlock(int fd,
        int err;
        localID next_off;               /* Offset of the next thing in the file
                                 * after the sort block */
-       off_t offset;           /* Offset into file, for checking */
+       localID offset;         /* Offset into file, for checking */
 
        /* Check to see if there even *is* a sort block */
        if (db->sortinfo_offset == 0L)
@@ -1695,7 +1697,7 @@ pdb_LoadSortBlock(int fd,
         * we've already passed the beginning of the sort block, as given
         * by its offset in the header.
         */
-       offset = lseek(fd, 0L, SEEK_CUR);       /* Find out where we are */
+       offset = (udword) lseek(fd, 0L, SEEK_CUR);      /* Find out where we are */
        if (offset != db->sortinfo_offset)
        {
                if (offset > db->sortinfo_offset)
@@ -1755,7 +1757,7 @@ pdb_LoadResources(int fd,
             i < db->numrecs;
             i++, rsrc = rsrc->next)
        {
-               off_t offset;           /* Current offset, for checking */
+               udword offset;          /* Current offset, for checking */
                udword next_off;        /* Offset of next resource in file */
 
                /* Sanity check: make sure we haven't stepped off the end
@@ -1785,7 +1787,7 @@ pdb_LoadResources(int fd,
                 * whether we've already passed the beginning of the
                 * resource, as given by its offset in the resource index.
                 */
-               offset = lseek(fd, 0L, SEEK_CUR);
+               offset = (udword) lseek(fd, 0L, SEEK_CUR);
                                        /* Find out where we are now */
                if (offset != rsrc->offset)
                {
@@ -1843,7 +1845,7 @@ pdb_LoadResources(int fd,
                /* Subtract this resource's index from that of the next
                 * thing, to get the size of this resource.
                 */
-               rsrc->data_len = next_off - rsrc->offset;
+               rsrc->data_len = (uword) (next_off - rsrc->offset);
 
                /* Allocate space for this resource */
                if ((rsrc->data = (ubyte *) malloc(rsrc->data_len)) == NULL)
@@ -1893,7 +1895,7 @@ pdb_LoadRecords(int fd,
             i < db->numrecs;
             i++, rec = rec->next)
        {
-               off_t offset;           /* Current offset, for checking */
+               udword offset;          /* Current offset, for checking */
                localID next_off;       /* Offset of next resource in file */
 
                /* Sanity check: make sure we haven't stepped off the end
@@ -1918,7 +1920,7 @@ pdb_LoadRecords(int fd,
                 * whether we've already passed the beginning of the
                 * record, as given by its offset in the record index.
                 */
-               offset = lseek(fd, 0L, SEEK_CUR);
+               offset = (udword) lseek(fd, 0L, SEEK_CUR);
                                        /* Find out where we are now */
                if (offset != rec->offset)
                {
@@ -1975,7 +1977,7 @@ pdb_LoadRecords(int fd,
                /* Subtract this record's index from that of the next one,
                 * to get the size of this record.
                 */
-               rec->data_len = next_off - rec->offset;
+               rec->data_len = (uword) (next_off - rec->offset);
 
                /* Allocate space for this record
                 * If there's a record with length zero, don't pass that to
index 984e22b747fff3e1e99ff81b62ecdd774d6e2fbf..61be647fb91b5ced699cf973764c0247abe3b970 100644 (file)
@@ -12,7 +12,7 @@
  * native format, convert them to Palm (big-endian) format, and write
  * them to a ubyte string.
  *
- * $Id: util.c,v 1.3 2004/01/18 01:24:41 robertl Exp $
+ * $Id: util.c,v 1.4 2005/03/18 03:56:35 robertl Exp $
  */
 
 #include "config.h"
@@ -65,7 +65,7 @@ get_ubyte(const ubyte **buf)
 }
 
 INLINE void
-put_ubyte(ubyte **buf, ubyte value)
+put_ubyte(ubyte **buf, const ubyte value)
 {
        **buf = value;
        ++(*buf);
@@ -83,7 +83,7 @@ get_uword(const ubyte **buf)
 }
 
 INLINE void
-put_uword(ubyte **buf, uword value)
+put_uword(ubyte **buf, const uword value)
 {
        **buf = (value >> 8) & 0xff;
        ++(*buf);
@@ -103,15 +103,15 @@ get_udword(const ubyte **buf)
 }
 
 INLINE void
-put_udword(ubyte **buf, udword value)
+put_udword(ubyte **buf, const udword value)
 {
-       **buf = (value >> 24) & 0xff;
+       **buf = (ubyte) ((value >> 24) & 0xff);
        ++(*buf);
-       **buf = (value >> 16) & 0xff;
+       **buf = (ubyte) ((value >> 16) & 0xff);
        ++(*buf);
-       **buf = (value >>  8) & 0xff;
+       **buf = (ubyte) ((value >>  8) & 0xff);
        ++(*buf);
-       **buf = value & 0xff;
+       **buf = (ubyte) (value & 0xff);
        ++(*buf);
 }
 #if TIME
index 10d028da44f7398e3ea86a223654aefe774c9d60..787e5be43648949ee4efe4a911e2544dad9b1921 100644 (file)
--- a/copilot.c
+++ b/copilot.c
@@ -88,7 +88,7 @@ data_read(void)
                waypoint *wpt_tmp;
                char *vdata;
 
-               wpt_tmp = xcalloc(sizeof(*wpt_tmp),1);
+               wpt_tmp = waypt_new();
 
                rec = (struct record *) pdb_rec->data;
                wpt_tmp->longitude =
@@ -158,7 +158,7 @@ copilot_writewpt(const waypoint *wpt)
        }
        vdata += strlen( vdata ) + 1;
 
-       opdb_rec = new_Record (0, 2, ct++, vdata-(char *)rec, (const ubyte *)rec);             
+       opdb_rec = new_Record (0, 2, ct++, (uword) (vdata-(char *)rec), (const ubyte *)rec);           
 
        if (opdb_rec == NULL) {
                fatal(MYNAME ": libpdb couldn't create record\n");
@@ -193,6 +193,7 @@ data_write(void)
 
 ff_vecs_t copilot_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
index 4d426382ca34638d59cda162c167186075ab872e..e2423a5b1f3b6dd34b322feb03c60eea50624986 100644 (file)
@@ -2,6 +2,7 @@
     Utilities for parsing Character Separated Value files (CSV)
 
     Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com)
+    Copyright (C) 2002-2005 Robert Lipe
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 extern char *xcsv_urlbase;
 extern char *prefer_shortnames;
 
+extern const char *gs_get_container(geocache_container t);
+extern geocache_container gs_mktype(const char *t);
+extern geocache_container gs_mkcont(const char *t);
+extern const char *gs_get_cachetype(geocache_type t);
+
 static double pathdist = 0;
 static double oldlon = 999;
 static double oldlat = 999;
@@ -77,14 +83,13 @@ csv_stringclean(const char *string, const char *chararray)
         while (*p1) {
             if (*cp == *p1) {
                 /* we don't want this character! */
-                strncpy(p1, p1 + 1, (p2 - p1));
+               memmove(p1, p1 + 1, (p2 - p1));
                 p1[p2 - p1] = '\0';
             }
             p1++;
         }
         cp++;
     }
-    
     return (tmp);
 }
 
@@ -146,7 +151,8 @@ csv_stringtrim(const char *string, const char *enclosure, int strip_max)
     }
 
     /* copy what's left over back into tmp. */
-    strncpy(tmp, p1, (p2 - p1) + 1);
+    memmove(tmp, p1, (p2 - p1) + 1);
+
     tmp[(p2 - p1) + 1] = '\0';
 
     return (tmp);
@@ -322,16 +328,19 @@ decdir_to_dec(const char * decdir)
  * human_to_dec() - convert a "human-readable" lat and/or lon to decimal
  * usage: human_to_dec( "N 41° 09.12' W 085° 09.36'", &lat, &lon );
  *        human_to_dec( "41 9 5.652 N", &lat, &lon );
+ *        
+ *        which: 0-no preference    1-prefer lat    2-prefer lon
  *****************************************************************************/
 
 static void
-human_to_dec( const char *instr, double *outlat, double *outlon )
+human_to_dec( const char *instr, double *outlat, double *outlon, int which )
 {
     double unk[3] = {999,999,999};
     double lat[3] = {999,999,999};
     double lon[3] = {999,999,999};
     int    latsign = 0;
     int    lonsign = 0;
+    int    unksign = 1;
    
     const char *cur;
     double *numres = unk;
@@ -388,6 +397,10 @@ human_to_dec( const char *instr, double *outlat, double *outlon )
                numres[numind] = atof(cur);
                while (cur && *cur && strchr("1234567890.",*cur)) cur++;
                break;
+           case '-':
+               unksign = -1;
+               cur++;
+               break;
            default:
                if (numres[numind] != 999) {
                    numind++;
@@ -401,6 +414,17 @@ human_to_dec( const char *instr, double *outlat, double *outlon )
        }
     }
     
+    if ( lat[0] == 999 && lon[0] == 999 ) {
+       if ( which == 1 ) {
+           lat[0] = unk[0]; lat[1] = unk[1]; lat[2] = unk[2];
+           latsign = unksign;
+       }
+       else if ( which == 2 ) {
+           lon[0] = unk[0]; lon[1] = unk[1]; lon[2] = unk[2];
+           lonsign = unksign;
+       }
+    }
+    
     if ( outlat ) {
        if ( lat[0] != 999 ) *outlat = lat[0];
        if ( lat[1] != 999 ) *outlat += lat[1]/60.0;
@@ -580,6 +604,37 @@ xcsv_epilogue_add(char *epilogue)
     xcsv_file.epilogue_lines++;
 }
 
+static
+time_t
+yyyymmdd_to_time(const char *s)
+{
+       int t = atol(s);
+       struct tm tm;
+
+       memset(&tm, 0, sizeof(tm));
+
+       tm.tm_mday = t % 100;
+       t = t / 100;
+       tm.tm_mon = t % 100 - 1;
+       t = t / 100;
+       tm.tm_year = t - 1900;
+       return mktime(&tm);
+}
+
+static 
+long 
+time_to_yyyymmdd(time_t t)
+{
+       long b;
+       struct tm *tm = gmtime(&t);
+
+       b = (1900 + tm->tm_year) * 10000 + 
+               (1 + tm->tm_mon) * 100 + 
+               tm->tm_mday;
+
+       return b;
+}
+
 /*****************************************************************************/
 /* xcsv_parse_val() - parse incoming data into the waypt structure.          */
 /* usage: xcsv_parse_val("-123.34", *waypt, *field_map)                      */
@@ -616,7 +671,7 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp)
     } else
     if (strcmp(fmp->key, "ICON_DESCR") == 0) {
        wpt->icon_descr = csv_stringtrim(s, "", 0);
-       wpt->icon_descr_is_dynamic = 1;
+       wpt->wpt_flags.icon_descr_is_dynamic = 1;
     } else
 
     /* LATITUDE CONVERSIONS**************************************************/
@@ -631,10 +686,10 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp)
     } else
     if (strcmp(fmp->key, "LAT_INT32DEG") == 0) {
        /* latitude as a 32 bit integer offset */
-       wpt->latitude = intdeg_to_dec(atof(s), 1);
+       wpt->latitude = intdeg_to_dec((int) atof(s), 1);
     } else
     if ( strcmp(fmp->key, "LAT_HUMAN_READABLE") == 0) {
-       human_to_dec( s, &wpt->latitude, &wpt->longitude );
+       human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 );
     } else
     if ( strcmp(fmp->key, "LAT_NMEA") == 0) {
        wpt->latitude = ddmm2degrees(wpt->latitude);
@@ -651,17 +706,17 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp)
     } else
     if (strcmp(fmp->key, "LON_INT32DEG") == 0) {
        /* longitude as a 32 bit integer offset  */
-       wpt->longitude = intdeg_to_dec(atof(s), 0);
+       wpt->longitude = intdeg_to_dec((int) atof(s), 0);
     } else
     if ( strcmp(fmp->key, "LON_HUMAN_READABLE") == 0) {
-       human_to_dec( s, &wpt->latitude, &wpt->longitude );
+       human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 );
     } else
     if ( strcmp(fmp->key, "LON_NMEA") == 0) {
        wpt->latitude = ddmm2degrees(wpt->longitude);
     } else
     /* LAT AND LON CONVERSIONS ********************************************/
     if ( strcmp(fmp->key, "LATLON_HUMAN_READABLE") == 0) {
-       human_to_dec( s, &wpt->latitude, &wpt->longitude );
+       human_to_dec( s, &wpt->latitude, &wpt->longitude, 0 );
     } else
     /* DIRECTIONS **********************************************************/
     if (strcmp(fmp->key, "LAT_DIR") == 0) {
@@ -690,6 +745,12 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp)
        /* Time as time_t */
        wpt->creation_time = atol(s);
      } else
+    if (strcmp(fmp->key, "YYYYMMDD_TIME") == 0) {
+       wpt->creation_time = yyyymmdd_to_time(s);
+    } else
+    if (strcmp(fmp->key, "GEOCACHE_LAST_FOUND") == 0) {
+       wpt->gc_data.last_found = yyyymmdd_to_time(s);
+    } else
 
     /* GEOCACHING STUFF ***************************************************/
     if (strcmp(fmp->key, "GEOCACHE_DIFF") == 0) {
@@ -707,6 +768,14 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp)
     if (strcmp(fmp->key, "GEOCACHE_CONTAINER") == 0) {
        wpt->gc_data.container = gs_mkcont(s);
     } else
+    if (strcmp(fmp->key, "GEOCACHE_HINT") == 0) {
+       wpt->gc_data.hint = csv_stringtrim(s, "", 0);
+    } else
+    if (strcmp(fmp->key, "GEOCACHE_PLACER") == 0) {
+       wpt->gc_data.placer = csv_stringtrim(s, "", 0);
+    } else
+       
+    /* OTHER STUFF ***************************************************/
     if ( strcmp( fmp->key, "PATH_DISTANCE_MILES") == 0) {
        /* Ignored on input */
     } else
@@ -759,7 +828,7 @@ xcsv_data_read(void)
         }
 
         if (strlen(buff)) {
-            wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
+            wpt_tmp = waypt_new();
 
             s = buff;
             s = csv_lineparse(s, xcsv_file.field_delimiter, "", linecount);
@@ -794,7 +863,7 @@ xcsv_data_read(void)
 }
 
 static void
-xcsv_resetpathlen()
+xcsv_resetpathlen(const route_head *head)
 {
     pathdist = 0;
     oldlat = 999;
@@ -824,15 +893,15 @@ xcsv_waypt_pr(const waypoint *wpt)
     oldlon = wpt->longitude;
     oldlat = wpt->latitude;
 
-    if (strcmp(xcsv_file.field_delimiter, "\\w") == 0)
+    if (xcsv_file.field_delimiter && strcmp(xcsv_file.field_delimiter, "\\w") == 0)
         write_delimiter = " ";
     else
         write_delimiter = xcsv_file.field_delimiter;
     
     if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) {
         if (wpt->description) {
-            if (global_opts.synthesize_shortnames)
-                shortname = mkshort(xcsv_file.mkshort_handle, wpt->description);
+            if (global_opts.synthesize_shortnames) 
+               shortname = mkshort_from_wpt(xcsv_file.mkshort_handle, wpt);
             else
                 shortname = csv_stringclean(wpt->description, xcsv_file.badchars);
         } else {
@@ -856,10 +925,8 @@ xcsv_waypt_pr(const waypoint *wpt)
            if (description) {
                    xfree(description);
            }
-           description = shortname;
-    }
-
-    if (description) {
+           description = shortname;
+    } else if (description) {
            char *odesc = description;
            description = str_utf8_to_ascii(odesc);
            xfree(odesc);
@@ -882,7 +949,12 @@ xcsv_waypt_pr(const waypoint *wpt)
             sprintf(buff, fmp->printfc, waypt_out_count + atoi(fmp->val));
         } else
         if (strcmp(fmp->key, "CONSTANT") == 0) {
-            sprintf(buff, fmp->printfc, fmp->val);
+           const char *cp = xcsv_get_char_from_constant_table(fmp->val);
+           if (cp) {
+                sprintf(buff, fmp->printfc, cp);
+           } else {
+               sprintf(buff, fmp->printfc, fmp->val);
+           }
         } else
         if (strcmp(fmp->key, "SHORTNAME") == 0) {
             sprintf(buff, fmp->printfc, 
@@ -1043,6 +1115,12 @@ xcsv_waypt_pr(const waypoint *wpt)
             /* time as a time_t variable */
             sprintf(buff, fmp->printfc, wpt->creation_time);
         } else
+        if (strcmp(fmp->key, "YYYYMMDD_TIME") == 0) {
+           sprintf(buff, fmp->printfc, time_to_yyyymmdd(wpt->creation_time));
+       } else
+        if (strcmp(fmp->key, "GEOCACHE_LAST_FOUND") == 0) {
+           sprintf(buff, fmp->printfc, time_to_yyyymmdd(wpt->gc_data.last_found));
+       } else
 
         /* GEOCACHE STUFF **************************************************/
         if (strcmp(fmp->key, "GEOCACHE_DIFF") == 0) {
@@ -1060,6 +1138,12 @@ xcsv_waypt_pr(const waypoint *wpt)
        if (strcmp(fmp->key, "GEOCACHE_TYPE") == 0) {
             /* Geocache Type */
             sprintf(buff, fmp->printfc, gs_get_cachetype(wpt->gc_data.type));
+        } else 
+       if (strcmp(fmp->key, "GEOCACHE_HINT") == 0) {
+           sprintf(buff, fmp->printfc, NONULL(wpt->gc_data.hint));
+        } else 
+       if (strcmp(fmp->key, "GEOCACHE_PLACER") == 0) {
+           sprintf(buff, fmp->printfc, NONULL(wpt->gc_data.placer));
         } else {
            /* this should probably never happen */
         }
@@ -1070,12 +1154,12 @@ xcsv_waypt_pr(const waypoint *wpt)
 
     fprintf (xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter);
 
-    if (shortname)
-        xfree(shortname);
-
     if (description && description != shortname)
         xfree(description);
 
+    if (shortname)
+        xfree(shortname);
+
     /* increment the index counter */
     waypt_out_count++;
 }
index e1e12cb169b1530680fba42971682b518383f1b8..a4d2d421074fd3fda9031d8b421cf89e813ff987 100644 (file)
@@ -62,6 +62,9 @@ xcsv_ofield_add(char *, char *, char *);
 void 
 xcsv_destroy_style(void);
 
+const char *
+xcsv_get_char_from_constant_table(char *key);
+
 /****************************************************************************/
 /* types required for various xcsv functions                                */
 /****************************************************************************/
diff --git a/defs.h b/defs.h
index 21fa18ae22d9e970d5296093977f6f882f81b85b..4ac800dcbc1f5bef3dac16dc45454982cbfebc85 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+    Copyright (C) 2002, 2003, 2004, 2005  Robert Lipe, robertlipe@usa.net
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 #include <stdarg.h>
 #include <stddef.h>
 #include "queue.h"
+#include "gbtypes.h"
 
 
 /*
 #  define snprintf _snprintf
 #endif
 
+/* Turn off numeric conversion warning */
+#if __WIN32__
+#pragma warning(disable:4244)
+#endif
+
 /*
  * Common definitions.   There should be no protocol or file-specific
  * data in this file.
@@ -81,11 +87,16 @@ typedef struct {
        unsigned int    masked_objective;
        int verbose_status;     /* set by GUI wrappers for status */
        int no_smart_icons;     
+       int no_smart_names;     
 } global_options;
 
 extern global_options global_opts;
 extern const char gpsbabel_version[];
 
+/* Short or Long XML Times */
+#define XML_SHORT_TIME 1
+#define XML_LONG_TIME 2
+
 /*
  * Extended data if waypoint happens to represent a geocache.  This is 
  * totally voluntary data...
@@ -99,7 +110,11 @@ typedef enum {
        gt_letterbox,
        gt_event,
        gt_suprise,
-       gt_webcam
+       gt_webcam,
+       gt_earth,
+       gt_locationless,
+       gt_benchmark, /* Extension to Groundspeak for GSAK */
+       gt_cito
 } geocache_type;
 
 typedef enum {
@@ -124,6 +139,8 @@ typedef struct {
        int diff; /* (multiplied by ten internally) */
        int terr; /* (likewise) */
        time_t exported;
+       time_t last_found;
+       char *placer; /* Placer name */
        char *hint; /* all these UTF8, XML entities removed, May be not HTML. */
        utf_string desc_short;
        utf_string desc_long; 
@@ -141,12 +158,28 @@ typedef struct xml_tag {
        struct xml_tag *child;
 } xml_tag ;
 
+typedef void (*an1_destroy)(void *);
+typedef void (*an1_copy)(void **, void *);
+typedef struct {
+       an1_destroy destroy;
+       an1_copy copy;
+} an1_base;
+
+/*
+ * Misc bitfields inside struct waypoint;
+ */
+typedef struct {
+       unsigned int icon_descr_is_dynamic:1; 
+       unsigned int shortname_is_synthetic:1;
+} wp_flags;
+
 /*
  * This is a waypoint, as stored in the GPSR.   It tries to not 
  * cater to any specific model or protocol.  Anything that needs to
  * be truncated, edited, or otherwise trimmed should be done on the
  * way to the target.
  */
+
 typedef struct {
        queue Q;                        /* Master waypoint q.  Not for use
                                           by modules. */
@@ -191,7 +224,8 @@ typedef struct {
        char *notes;
        char *url;
        char *url_link_text;
-       int icon_descr_is_dynamic;
+
+       wp_flags wpt_flags;
        const char *icon_descr;
        time_t creation_time;   /* standardized in UTC/GMT */
        int centiseconds;       /* Optional hundredths of a second. */
@@ -203,11 +237,14 @@ typedef struct {
         * This causes it to be removed last.
         * This is currently used by the saroute input filter to give named
         * waypoints (representing turns) a higher priority.
+        * This is also used by the google input filter because they were
+        * nice enough to use exactly the same priority scheme.
         */
        int route_priority;
        
        geocache_data gc_data;
        xml_tag *gpx_extras;
+       an1_base *an1_extras;
        void *extra_data;       /* Extra data added by, say, a filter. */
 } waypoint;
 
@@ -218,6 +255,7 @@ typedef struct {
        char *rte_desc;
        int rte_num;
        int rte_waypt_ct;               /* # waypoints in waypoint list */
+       an1_base *an1_extras;
 } route_head;
 
 /*
@@ -262,6 +300,7 @@ void waypt_compute_bounds(bounds *);
 void waypt_flush(queue *);
 void waypt_flush_all(void);
 unsigned int waypt_count(void);
+void set_waypt_count(unsigned int nc);
 void free_gpx_extras (xml_tag * tag);
 void xcsv_setup_internal_style(const char *style_buf);
 void xcsv_read_internal_style(const char *style_buf);
@@ -298,9 +337,11 @@ void *MKSHORT_NEW_HANDLE(DEBUG_PARAMS);
 #define mkshort( a, b) MKSHORT(a,b,__FILE__, __LINE__)
 #define mkshort_new_handle() MKSHORT_NEW_HANDLE(__FILE__,__LINE__)
 #endif
+char *mkshort_from_wpt(void *h, const waypoint *wpt);
 void mkshort_del_handle(void *h);
 void setshort_length(void *, int n);
 void setshort_badchars(void *, const char *);
+void setshort_goodchars(void *, const char *);
 void setshort_mustupper(void *, int n);
 void setshort_mustuniq(void *, int n);
 void setshort_whitespace_ok(void *, int n);
@@ -318,15 +359,36 @@ void      vmem_free(vmem_t*);
 void   vmem_realloc(vmem_t*, size_t);
 
 
-#define ARGTYPE_UNKNOWN  0
-#define ARGTYPE_INT      0x00000001
-#define ARGTYPE_FLOAT    0x00000002
-#define ARGTYPE_STRING   0x00000003
-#define ARGTYPE_BOOL     0x00000004
-#define ARGTYPE_FILE     0x00000005
-#define ARGTYPE_OUTFILE  0x00000006
-#define ARGTYPE_REQUIRED 0x40000000
-#define ARGTYPE_HIDDEN   0x20000000
+#define ARGTYPE_UNKNOWN    0x00000000
+#define ARGTYPE_INT        0x00000001
+#define ARGTYPE_FLOAT      0x00000002
+#define ARGTYPE_STRING     0x00000003
+#define ARGTYPE_BOOL       0x00000004
+#define ARGTYPE_FILE       0x00000005
+#define ARGTYPE_OUTFILE    0x00000006
+
+/* REQUIRED means that the option is required to be set. 
+ * See also BEGIN/END_REQ */
+#define ARGTYPE_REQUIRED   0x40000000
+
+/* HIDDEN means that the option does not appear in help texts.  Useful
+ * for debugging or testing options */
+#define ARGTYPE_HIDDEN     0x20000000
+
+/* BEGIN/END_EXCL mark the beginning and end of an exclusive range of
+ * options. No more than one of the options in the range may be selected 
+ * or set. If exactly one must be set, use with BEGIN/END_REQ
+ * Both of these flags set is just like neither set, so avoid doing that. */
+#define ARGTYPE_BEGIN_EXCL 0x10000000
+#define ARGTYPE_END_EXCL   0x08000000
+
+/* BEGIN/END_REQ mark the beginning and end of a required range of 
+ * options.  One or more of the options in the range MUST be selected or set.
+ * If exactly one must be set, use with BEGIN/END_EXCL 
+ * Both of these flags set is synonymous with REQUIRED, so use that instead
+ * for "groups" of exactly one option. */
+#define ARGTYPE_BEGIN_REQ  0x04000000
+#define ARGTYPE_END_REQ    0x02000000 
 
 #define ARGTYPE_TYPEMASK 0x00000fff
 #define ARGTYPE_FLAGMASK 0xfffff000
@@ -345,11 +407,29 @@ typedef enum {
        ff_type_serial,         /* format describes a serial protoco (GUI can display port names) */
 } ff_type;
 
+typedef enum {
+       ff_cap_rw_wpt,
+       ff_cap_rw_trk,
+       ff_cap_rw_rte
+} ff_cap_array;
+
+typedef enum {
+       ff_cap_none,
+       ff_cap_read = 1,
+       ff_cap_write = 2
+} ff_cap;
+#define FF_CAP_RW_ALL \
+       { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write }
+
+#define FF_CAP_RW_WPT \
+       { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none}
+
 /*
  *  Describe the file format to the caller.
  */
 typedef struct ff_vecs {
        ff_type type;
+       ff_cap cap[3];
        ff_init rd_init;
        ff_init wr_init;
        ff_deinit rd_deinit;
@@ -377,6 +457,7 @@ typedef struct filter_vecs {
 void waypt_init(void);
 void route_init(void);
 void waypt_disp(const waypoint *);
+void waypt_status_disp(int total_ct, int myct);
 void fatal(const char *, ...)
 #if __GNUC__
        __attribute__ ((__format__ (__printf__, 1, 2)))
@@ -387,13 +468,13 @@ void warning(const char *, ...)
        __attribute__ ((__format__ (__printf__, 1, 2)))
 #endif
        ;
-ff_vecs_t *find_vec(char *, char **);
+ff_vecs_t *find_vec(char * const, char **);
 void disp_vecs(void);
 void exit_vecs(void);
 void disp_formats(int version);
-void printposn(double c, int is_lat);
+void printposn(const double c, int is_lat);
 
-filter_vecs_t * find_filter_vec(char *, char **);
+filter_vecs_t * find_filter_vec(char * const, char **);
 void free_filter_vec(filter_vecs_t *);
 void disp_filters(int version);
 void disp_filter_vecs(void);
@@ -448,8 +529,10 @@ void xfprintf(const char *errtxt, FILE *stream, const char *format, ...);
 void xfputs(const char *errtxt, const char *s, FILE *stream);
 
 int case_ignore_strcmp(const char *s1, const char *s2);
+int case_ignore_strncmp(const char *s1, const char *s2, int n);
 
-char *strsub(char *s, char *search, char *replace);
+char *strsub(const char *s, const char *search, const char *replace);
+char *gstrsub(const char *s, const char *search, const char *replace);
 void rtrim(char *s);
 signed int get_tz_offset(void);
 time_t current_time(void);
@@ -463,7 +546,7 @@ char * str_utf8_to_cp1252( const char * str );
 char * str_utf8_to_ascii( const char * str );
 
 /* this lives in gpx.c */
-time_t xml_parse_time( char *cdatastr );
+time_t xml_parse_time( const char *cdatastr );
        
 xml_tag *xml_findfirst( xml_tag *root, char *tagname );
 xml_tag *xml_findnext( xml_tag *root, xml_tag *cur, char *tagname );
index dd01469753a1678b3da9d2a888f744b549e255e2..3e65936bfe37a4399a22b3e315446b6d644e5673 100644 (file)
--- a/delgpl.c
+++ b/delgpl.c
@@ -46,7 +46,7 @@ gpl_rd_init(const char *fname)
 {
        gplfile_in = xfopen(fname, "rb", MYNAME);
        if (sizeof(struct gpl_point) != 56) {
-               fatal(MYNAME, ": gpl_point is %d instead of 56.\n", 
+               fatal(MYNAME ": gpl_point is %d instead of 56.\n", 
                                sizeof(struct gpl_point));
        }
 }
@@ -56,7 +56,6 @@ gpl_read(void)
 {
        waypoint *wpt_tmp;
        route_head *track_head;
-       int br;
        gpl_point_t gp;
        double alt_feet;
 
@@ -114,6 +113,7 @@ gpl_write(void)
 
 ff_vecs_t gpl_vecs = {
        ff_type_file,
+       { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none },
        gpl_rd_init,    
        gpl_wr_init,    
        gpl_rd_deinit,  
index 321834754e3621cced845f9d185989d0959656aa..5556be28ee73bef21e17f8b11bf97d3afcf3bd8d 100644 (file)
@@ -31,9 +31,9 @@ static char *correct_coords = NULL;
 static
 arglist_t dup_args[] = {
        {"shortname", &snopt, "Suppress duplicate waypoints based on name",
-               NULL, ARGTYPE_BOOL},
+               NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL},
        {"location", &lcopt, "Suppress duplicate waypoint based on coords",
-               NULL, ARGTYPE_BOOL},
+               NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL},
        {"all", &purge_duplicates, "Suppress all instances of duplicates",
                NULL, ARGTYPE_BOOL},
        {"correct", &correct_coords, "Use coords from duplicate points", 
index 827d2057f9cb4f65a1fb2df54be64787cc8d8807..bcfab3f03893bf150d4a61b042f1afe116f0a3e1 100644 (file)
--- a/easygps.c
+++ b/easygps.c
@@ -25,7 +25,7 @@
 static FILE *file_in;
 static FILE *file_out;
 static void *mkshort_handle;
-static char *deficon = NULL;
+/* static char *deficon = NULL; */
 
 #define MYNAME "EasyGPS"
 
@@ -263,6 +263,7 @@ data_write(void)
 
 ff_vecs_t easygps_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
index f81c545b71c3e836eb62baf89ecf39f86f0845f1..238d93e102216c8fec45c7e29bebe4702c68c30f 100644 (file)
@@ -1,7 +1,7 @@
 /*
     Describe vectors containing filter operations.
  
-    Copyright (C) 2002,2004 Robert Lipe, robertlipe@usa.net
+    Copyright (C) 2002,2004,2005 Robert Lipe, robertlipe@usa.net
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -198,6 +198,15 @@ disp_filter_vecs(void)
        }
 }
 
+static signed int
+alpha (const void *a, const void *b)
+{
+        const fl_vecs_t *const ap = a;
+        const fl_vecs_t *const bp = b;
+
+        return strcasecmp(ap->desc , bp->desc);
+}
+
 /*
  *  Display the available formats in a format that's easy to machine
  *  parse.   Typically invoked by programs like graphical wrappers to
@@ -208,6 +217,12 @@ disp_filters(int version)
 {
        fl_vecs_t *vec;
 
+       qsort(filter_vec_list, 
+               sizeof(filter_vec_list) / sizeof(filter_vec_list[0]) - 1,
+               sizeof(filter_vec_list[0]),
+               alpha);
+               
+
        switch(version) {
        case 0:
                for (vec = filter_vec_list; vec->vec; vec++) {
index 898fc59ac8b95fe9b0c062498bd4ce4ea77b8643..a25b363c052f8002326185ed041610a5ee762b72 100644 (file)
--- a/garmin.c
+++ b/garmin.c
@@ -36,6 +36,9 @@ static char *getposn = NULL;
 static char *poweroff = NULL;
 static char *snlen = NULL;
 static char *snwhiteopt = NULL;
+static char *deficon = NULL;
+/* Technically, even this is a little loose as spaces arent allowed */
+static char valid_waypt_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789";
 
 static
 arglist_t garmin_args[] = {
@@ -43,6 +46,7 @@ arglist_t garmin_args[] = {
                ARGTYPE_INT },
        { "snwhite", &snwhiteopt, "(0/1) Allow whitespace synth. shortnames",
                NULL, ARGTYPE_BOOL},
+       { "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING },
        { "get_posn", &getposn, "Return current position as a waypoint", 
                NULL, ARGTYPE_BOOL},
        { "power_off", &poweroff, "Command unit to power itself down", 
@@ -125,6 +129,11 @@ rw_init(const char *fname)
                        break;
                        
        }
+       if (global_opts.debug_level > 0)  {
+               fprintf(stderr, "Waypoint type: %d\n"
+                       "Chosen waypoint length %d\n",
+                        gps_waypt_type, short_length);
+       }
        /*
         * If the user provided a short_length, override the calculated value.
         */
@@ -136,6 +145,7 @@ rw_init(const char *fname)
        if (snwhiteopt)
                setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt));
 
+       setshort_goodchars(mkshort_handle, valid_waypt_chars);
        setshort_mustupper(mkshort_handle, 1);
 
 }
@@ -158,6 +168,7 @@ waypt_read_cb(int total_ct, GPS_PWay *way)
                i++;
                waypt_status_disp(total_ct, i);
        }
+       return 0;
 }
 
 static void
@@ -212,6 +223,8 @@ waypt_read(void)
                } else {
                        wpt_tmp->altitude = way[i]->alt;
                }
+               if (way[i]->Time_populated)
+                       wpt_tmp->creation_time = way[i]->Time;
                
                waypt_add(wpt_tmp);
                GPS_Way_Del(&way[i]);
@@ -233,7 +246,7 @@ track_read(void)
 
        ntracks = GPS_Command_Get_Track(portname, &array);
 
-       if ( ntracks == 0 )
+       if ( ntracks <= 0 )
                return;
 
        for(i = 0; i < ntracks; i++) {
@@ -265,7 +278,6 @@ track_read(void)
                                sprintf(trk_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf);
                        }
                        trk_seg_num++;
-                       trk_head->rte_num = trk_num;
                        trk_num++;
                        track_add_head(trk_head);
                }
@@ -281,8 +293,8 @@ track_read(void)
                route_add_wpt(trk_head, wpt);
        }
 
-       while(--ntracks) {
-               GPS_Track_Del(&array[ntracks]);
+       while(ntracks) {
+               GPS_Track_Del(&array[--ntracks]);
        }
        xfree(array);
 }
@@ -294,15 +306,13 @@ route_read(void)
        int32 nroutepts;
        int i;
        GPS_PWay *array;
+  route_head *rte_head;
 
        nroutepts = GPS_Command_Get_Route(portname, &array);
 
-       fprintf(stderr, "Routes %d\n", (int) nroutepts);
+//     fprintf(stderr, "Routes %d\n", (int) nroutepts);
 #if 1
        for (i = 0; i < nroutepts; i++) {
-               route_head *rte_head;
-               waypoint * wpt_tmp;
-
                if (array[i]->isrte) {
                        char *csrc = NULL;
                        /* What a horrible API has libjeeps for making this
@@ -313,18 +323,16 @@ route_read(void)
                                case 202: csrc = array[i]->rte_ident; break;
                                default: break;
                        }
-               rte_head = route_head_alloc();
-               route_add_head(rte_head);
-               if (csrc) {
-                       rte_head->rte_name = xstrdup(csrc);
-               }
-               ;
-               
+      rte_head = route_head_alloc();
+      route_add_head(rte_head);
+      if (csrc) {
+        rte_head->rte_name = xstrdup(csrc);
+      }
                } else { 
                        if (array[i]->islink)  {
                                continue; 
                        } else {
-                               wpt_tmp = xcalloc(sizeof (*wpt_tmp), 1);
+                               waypoint *wpt_tmp = xcalloc(sizeof (*wpt_tmp), 1);
                                wpt_tmp->latitude = array[i]->lat;
                                wpt_tmp->longitude = array[i]->lon;
                                wpt_tmp->shortname = array[i]->ident;
@@ -378,7 +386,7 @@ sane_GPS_Way_New(void)
        way->addr[0] = 0;
        way->cross_road[0] = 0;
        way->cross_road[0] = 0;
-       way->dpth = 1.0e25;
+       way->dpth = 1.0e25f;
        way->wpt_class = 0;
 
        return way;
@@ -397,6 +405,23 @@ waypt_write_cb(GPS_PWay *way)
        return 0;
 }
 
+/* 
+ * If we're not using smart icons, try to put the cache info in the
+ * description.
+ */
+const char *
+get_gc_info(waypoint *wpt)
+{
+       if (global_opts.no_smart_icons) {
+               if (wpt->gc_data.type == gt_virtual) return  "V ";
+               if (wpt->gc_data.type == gt_unknown) return  "? ";
+               if (wpt->gc_data.type == gt_multi) return  "Mlt ";
+               if (wpt->gc_data.container == gc_micro) return  "M ";
+               if (wpt->gc_data.container == gc_small) return  "S ";
+       }
+       return "";
+}
+
 static void
 waypoint_write(void)
 {
@@ -406,7 +431,6 @@ waypoint_write(void)
        queue *elem, *tmp;
        extern queue waypt_head;
        GPS_PWay *way;
-       extern int32 gps_save_id;
        int icon;
 
        way = xcalloc(n,sizeof(*way));
@@ -428,21 +452,28 @@ waypoint_write(void)
                if(wpt->description) src = wpt->description;
                if(wpt->notes) src = wpt->notes;
 
-               ident = global_opts.synthesize_shortnames ? 
-                               mkshort(mkshort_handle, src) : 
-                               wpt->shortname;
+               /* 
+                * mkshort will do collision detection and namespace 
+                * cleaning 
+                */
+               ident = mkshort(mkshort_handle, 
+                       global_opts.synthesize_shortnames ? src : 
+                       wpt->shortname);
                /* Should not be a strcpy as 'ident' isn't really a C string,
                 * but rather a garmin "fixed length" buffer that's padded
                 * to the end with spaces.  So this is NOT (strlen+1).
                 */
                memcpy(way[i]->ident, ident, strlen(ident));
+
                if (global_opts.synthesize_shortnames) { 
                        xfree(ident);
                }
                way[i]->ident[sizeof(way[i]->ident)-1] = 0;
 
-               if (wpt->gc_data.diff && wpt->gc_data.terr) {
-                       snprintf(obuf, sizeof(obuf), "%d/%d %s", 
+               if (!global_opts.no_smart_icons && 
+                    wpt->gc_data.diff && wpt->gc_data.terr) {
+                       snprintf(obuf, sizeof(obuf), "%s%d/%d %s", 
+                                       get_gc_info(wpt),
                                        wpt->gc_data.diff, wpt->gc_data.terr, 
                                        src);
                        memcpy(way[i]->cmnt, obuf, strlen(obuf));
@@ -452,10 +483,14 @@ waypoint_write(void)
                way[i]->lon = wpt->longitude;
                way[i]->lat = wpt->latitude;
 
-               if (get_cache_icon(wpt)) {
-                       icon = mps_find_icon_number_from_desc(get_cache_icon(wpt), PCX);
+               if (deficon) {
+                       icon = mps_find_icon_number_from_desc(deficon, PCX);
                } else {
-                       icon = mps_find_icon_number_from_desc(wpt->icon_descr, PCX);
+                       if (get_cache_icon(wpt)) {
+                               icon = mps_find_icon_number_from_desc(get_cache_icon(wpt), PCX);
+                       } else {
+                               icon = mps_find_icon_number_from_desc(wpt->icon_descr, PCX);
+                       }
                }
 
                /* For units that support tiny numbers of waypoints, just
@@ -470,6 +505,7 @@ waypoint_write(void)
                } else {
                        way[i]->alt = wpt->altitude;
                }
+               way[i]->Time = wpt->creation_time;
                i++;
        }
 
@@ -586,7 +622,6 @@ track_write(void)
 
        tx_tracklist = xcalloc(n, sizeof(GPS_PTrack));
        cur_tx_tracklist_entry = tx_tracklist;
-
        for (i = 0; i < n; i++) {
                tx_tracklist[i] = GPS_Track_New();
        }
@@ -602,7 +637,7 @@ track_write(void)
 }
 
 static void
-data_write()
+data_write(void)
 {
        if (poweroff) {
                return;
@@ -619,6 +654,7 @@ data_write()
 
 ff_vecs_t garmin_vecs = {
        ff_type_serial,
+       FF_CAP_RW_ALL,
        rw_init,
        rw_init,
        rw_deinit,
index f7bd4ff24ab922481c7d1fb98fb5acd2cb2a2c8f..f0d97908372973e1143b8c83a8ae9a99ec11771d 100644 (file)
@@ -48,6 +48,7 @@ icon_mapping_t garmin_icon_table[] = {
        {    71,  8200, "City (Large)" },
        {    70,  8199, "City (Medium)" },
        {    69,  8198, "City (Small)" },
+       {    69,  8198, "Small City" },
        {    97,  8237, "Civil" },
        {   119,  8262, "Contact, Afro" },
        {   120,  8272, "Contact, Alien" },
@@ -179,30 +180,30 @@ icon_mapping_t garmin_icon_table[] = {
         * numbers "-2" to signify that as a problem until we can create
         * these in a .mps or .gdb file and see their representation there.
         */
-       {    -2,  7680, "Custom 1" },
-       {    -2,  7681, "Custom 2" },
-       {    -2,  7682, "Custom 3" },
-       {    -2,  7683, "Custom 4" },
-       {    -2,  7684, "Custom 5" },
-       {    -2,  7685, "Custom 6" },
-       {    -2,  7686, "Custom 7" },
-       {    -2,  7687, "Custom 8" },
-       {    -2,  7688, "Custom 9" },
-       {    -2,  7689, "Custom 10" },
-       {    -2,  7690, "Custom 11" },
-       {    -2,  7691, "Custom 12" },
-       {    -2,  7692, "Custom 13" },
-       {    -2,  7693, "Custom 14" },
-       {    -2,  7694, "Custom 15" },
-       {    -2,  7695, "Custom 16" },
-       {    -2,  7696, "Custom 17" },
-       {    -2,  7697, "Custom 18" },
-       {    -2,  7698, "Custom 19" },
-       {    -2,  7799, "Custom 20" },
-       {    -2,  7700, "Custom 21" },
-       {    -2,  7701, "Custom 22" },
-       {    -2,  7702, "Custom 23" },
-       {    -2,  7703, "Custom 24" },
+       {    -2,  7680, "Custom 0" },
+       {    -2,  7681, "Custom 1" },
+       {    -2,  7682, "Custom 2" },
+       {    -2,  7683, "Custom 3" },
+       {    -2,  7684, "Custom 4" },
+       {    -2,  7685, "Custom 5" },
+       {    -2,  7686, "Custom 6" },
+       {    -2,  7687, "Custom 7" },
+       {    -2,  7688, "Custom 8" },
+       {    -2,  7689, "Custom 9" },
+       {    -2,  7690, "Custom 10" },
+       {    -2,  7691, "Custom 11" },
+       {    -2,  7692, "Custom 12" },
+       {    -2,  7693, "Custom 13" },
+       {    -2,  7694, "Custom 14" },
+       {    -2,  7695, "Custom 15" },
+       {    -2,  7696, "Custom 16" },
+       {    -2,  7697, "Custom 17" },
+       {    -2,  7698, "Custom 18" },
+       {    -2,  7699, "Custom 19" },
+       {    -2,  7700, "Custom 20" },
+       {    -2,  7701, "Custom 21" },
+       {    -2,  7702, "Custom 22" },
+       {    -2,  7703, "Custom 23" },
 
        {    92,  8227, "Micro-Cache" },        /* icon for "Toll Booth" */
        {    48,   161, "Virtual cache" },      /* icon for "Scenic Area" */
@@ -213,5 +214,30 @@ icon_mapping_t garmin_icon_table[] = {
        {    47,   160, "Event Cache" },        /* Icon for "Event" */
        {    90,  8221, "Webcam Cache" },       /* Icon for "Live Theatre" */
 
+       /* MapSource V6.x */
+       
+       {   140,  8286, "Flag, Red" },          
+       {   141,  8284, "Flag, Blue" },
+       {   142,  8285, "Flag, Green" },
+       {   143,  8289, "Pin, Red" },
+       {   144,  8287, "Pin, Blue" },
+       {   145,  8288, "Pin, Green" },
+       {   146,  8292, "Diamond, Red" },
+       {   147,  8290, "Diamond, Blue" },
+       {   148,  8291, "Diamond, Green" },
+       {   149,  8293, "Bike Trail" },
+       {   150,   181, "Fishing Hot Spot Facility" }, 
+       {   151,  8249, "Police Station"}, 
+       {   152,  8251, "Ski Resort" }, 
+       {   153,  8252, "Ice Skating" }, 
+       {   154,  8253, "Wrecker" }, 
+       {   155,   184, "Anchor Prohibited" }, 
+       {   156,   185, "Beacon" }, 
+       {   157,   186, "Coast Guard" }, 
+       {   158,   187, "Reef" }, 
+       {   159,   188, "Weed Bed" }, 
+       {   160,   189, "Dropoff" }, 
+       {   161,   190, "Dock" }, 
+       
        {    -1,    -1, NULL },
 };
diff --git a/gbtypes.h b/gbtypes.h
new file mode 100644 (file)
index 0000000..bdbc8ce
--- /dev/null
+++ b/gbtypes.h
@@ -0,0 +1,48 @@
+/*
+    Abstract fixed size data types.
+
+    Copyright (C) 2005 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+/*
+ *  If this is a problem and any interesting system doesn't have the C99-ism
+ *  of <stdint.h> we'll come up with something more clever that'll likely
+ *  include a gross collection of  __STDC_VERSION >= 199901L  || __GNUC__
+ */
+
+#if defined(_MSC_VER)
+
+typedef unsigned long gbuint32;
+typedef unsigned short gbuint16;
+typedef long gbint32;
+typedef short gbint16;
+
+#else
+
+# if defined (__FreeBSD__)
+#  include <inttypes.h>
+# else
+#  include <stdint.h>
+# endif
+
+typedef uint32_t       gbuint32;
+typedef uint16_t       gbuint16;
+typedef  int32_t        gbint32;
+typedef  int16_t        gbint16;
+
+#endif // defined(_MSC_VER)
diff --git a/gcdb.c b/gcdb.c
index bde86f8efe8624c11718a155b301fd27ffa70339..8f9727736ad8bdaa2fee3724de5ca0516d05ecec 100644 (file)
--- a/gcdb.c
+++ b/gcdb.c
@@ -293,7 +293,7 @@ gcdb_write_wpt(const waypoint *wpt)
         */
        reclen = gcdb_add_to_rec(rec, NULL, 0, NULL);
 
-       opdb_rec = new_Record(0, 2, ct++, reclen, (const ubyte *)rec);
+       opdb_rec = new_Record(0, 2, ct++, (uword) reclen, (const ubyte *)rec);
 
        if (opdb_rec == NULL) {
                fatal(MYNAME ": libpdb couldn't create record\n");
@@ -331,6 +331,7 @@ data_write(void)
 
 ff_vecs_t gcdb_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
diff --git a/geo.c b/geo.c
index 9e8eeca10af008cc95b7b389c50a95fef1daed9c..c8ace7244c0d4def231660419f110069b4b74704 100644 (file)
--- a/geo.c
+++ b/geo.c
 
  */
 #include "defs.h"
-#if !NO_EXPAT
-#include <expat.h>
-static XML_Parser psr;
-#endif
+#include "xmlgeneric.h"
 
-static int in_wpt;
-static int in_name;
-static int in_link;
-static int in_type;
-static int in_cdata;
-static char *cdatastr;
-static char *typestr;
 static char *deficon = NULL;
 
 static waypoint *wpt_tmp;
@@ -57,185 +47,106 @@ geo_read(void)
 {
 }
 #else
-static void
-tag_coord(const char **attrv)
-{
-       const char **avp = &attrv[0];
-
-
-       while (*avp) { 
-               if (strcmp(avp[0], "lat") == 0) {
-                       sscanf(avp[1], "%lf", 
-                               &wpt_tmp->latitude);
-               }
-               else if (strcmp(avp[0], "lon") == 0) {
-                       sscanf(avp[1], "%lf", 
-                               &wpt_tmp->longitude);
-               }
-               avp+=2;
-       }
+
+static xg_callback     wpt_s, wpt_e;
+static xg_callback     wpt_link_s, wpt_link;
+static xg_callback     wpt_name, wpt_name_s, wpt_type, wpt_coord;
+
+static 
+xg_tag_mapping loc_map[] = {
+       { wpt_s,        cb_start,       "/loc/waypoint" },
+       { wpt_e,        cb_end,         "/loc/waypoint" },
+       { wpt_name_s,   cb_start,       "/loc/waypoint/name" },
+       { wpt_name,     cb_cdata,       "/loc/waypoint/name" },
+       { wpt_type,     cb_cdata,       "/loc/waypoint/type" },
+       { wpt_link_s,   cb_start,       "/loc/waypoint/link" },
+       { wpt_link,     cb_cdata,       "/loc/waypoint/link" },
+       { wpt_coord,    cb_start,       "/loc/waypoint/coord" },
+       { NULL,         0,              NULL }
+};
+
+void wpt_s(const char *args, const char **unused) 
+{ 
+//     wpt_tmp = waypt_new();
+       wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
 }
 
-static void
-tag_name(const char **attrv)
+void wpt_e(const char *args, const char **unused)
 {
-       const char **avp = &attrv[0];
-       while (*avp) { 
-               if (strcmp(avp[0], "id") == 0) {
-                       wpt_tmp->shortname = xstrdup(avp[1]);
-               }
-               avp+=2;
-       }
+       waypt_add(wpt_tmp);
 }
 
-static void
-tag_type(const char **attrv)
+void wpt_name_s(const char *args, const char **attrv)
 {
-       const char **avp = &attrv[0];
-       while (*avp) { 
-               if (strcmp(avp[0], "type") == 0) {
-                       wpt_tmp->icon_descr = xstrdup(avp[1]);
-               }
-               avp+=2;
-       }
+        const char **avp = &attrv[0];
+        while (*avp) {
+                if (0 == strcmp(avp[0], "id")) {
+                        wpt_tmp->shortname = xstrdup(avp[1]);
+                }
+                avp+=2;
+        }
 }
 
-static void
-tag_link(const char **attrv)
+void wpt_name(const char *args, const char **unused)
 {
-       const char **avp = &attrv[0];
-       while (*avp) { 
-               if (strcmp(avp[0], "text") == 0) {
-                       wpt_tmp->url_link_text = xstrdup(avp[1]);
-               }
-               avp+=2;
-       }
+       if (args) wpt_tmp->description = xstrappend(wpt_tmp->description,args);
 }
 
-static void
-geo_start(void *data, const char *el, const char **attr)
+void wpt_link_s(const char *args, const char **attrv)
 {
-
-       if (in_wpt) {
-               if (strcmp(el, "ele") == 0) {
-                       wpt_tmp->altitude = atoi(attr[1]);
-               }
-               else if (strcmp(el, "name") == 0) {
-                       tag_name(attr);
-               }
-               else if (strcmp(el, "coord") == 0) {
-                       tag_coord(attr);
-               }
-               else if (strcmp(el, "type") == 0) {
-                       tag_type(attr);
-               }
-       }
-
-       if (strcmp(el, "waypoint") == 0) {
-               wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
-               in_wpt++;
-       } else if (strcmp(el, "name") == 0) {
-               in_name++;
-       } else if (strcmp(el, "type") == 0) {
-               tag_type(attr);
-               in_type++;
-       } else if (strcmp(el, "link") == 0) {
-               tag_link(attr);
-               in_link++;
-       }
+        const char **avp = &attrv[0];
+        while (*avp) {
+                if (0 == strcmp(avp[0], "text")) {
+                        wpt_tmp->url_link_text = xstrdup(avp[1]);
+                }
+                avp+=2;
+        }
+}
+void wpt_link(const char *args, const char **attrv)
+{
+       wpt_tmp->url = xstrdup(args);
 }
 
-static void
-geo_end(void *data, const char *el)
+void wpt_type(const char *args, const char **unused)
 {
-       if (in_cdata) {
-               if (in_name) {
-                       wpt_tmp->description = xstrdup(cdatastr);
-               }
-               if (in_link) {
-                       wpt_tmp->url = xstrdup(cdatastr);
-               }
-               in_cdata--;
-               memset(cdatastr,0, MY_CBUF);
-       }
-       if (strcmp(el, "waypoint") == 0) {
-               waypt_add(wpt_tmp);
-               in_wpt--;
-       }
-       else if (strcmp(el, "name") == 0) {
-               in_name--;
-       }
-       else if (strcmp(el, "type") == 0) {
-               wpt_tmp->icon_descr_is_dynamic = 1;
-               wpt_tmp->icon_descr = xstrdup(typestr);
-               memset(typestr,0, MY_CBUF);
-               in_type--;
-       }
-       else if (strcmp(el, "link") == 0) {
-               in_link--;
-       }
+       wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1;
+       wpt_tmp->icon_descr = xstrdup(args);
 }
 
-static void
-geo_cdata(void *dta, const XML_Char *s, int len)
+void wpt_coord(const char *args, const char **attrv)
 {
-       char *estr;
-       if (in_name || in_link) {
-               estr = cdatastr + strlen(cdatastr);
-               memcpy(estr, s, len); 
-               in_cdata++;
-       }
-       if (in_type) {
-               estr = typestr + strlen(typestr);
-               memcpy(estr, s, len); 
-       }
+        const char **avp = &attrv[0];
+
+        while (*avp) {
+                if (strcmp(avp[0], "lat") == 0) {
+                        sscanf(avp[1], "%lf",
+                                &wpt_tmp->latitude);
+                }
+                else if (strcmp(avp[0], "lon") == 0) {
+                        sscanf(avp[1], "%lf",
+                                &wpt_tmp->longitude);
+                }
+                avp+=2;
+        }
 }
 
 void
 geo_rd_init(const char *fname)
 {
-       fd = xfopen(fname, "r", MYNAME);
-
-       psr = XML_ParserCreate(NULL);
-       if (!psr) {
-               fatal(MYNAME ":Cannot create XML parser\n");
-       }
-
-       XML_SetElementHandler(psr, geo_start, geo_end);
-       cdatastr = xcalloc(MY_CBUF,1);
-       typestr = xcalloc(MY_CBUF,1);
-       XML_SetCharacterDataHandler(psr, geo_cdata);
+       xml_init(fname, loc_map);
 }
 
 void
 geo_read(void)
 {
-       int len;
-       char buf[MY_CBUF];
-       
-       while ((len = fread(buf, 1, sizeof(buf), fd))) {
-               if (!XML_Parse(psr, buf, len, feof(fd))) {
-                       fatal(MYNAME ":Parse error at %d: %s\n", 
-                               XML_GetCurrentLineNumber(psr),
-                               XML_ErrorString(XML_GetErrorCode(psr)));
-               }
-       }
-
-       XML_ParserFree(psr);
+       xml_read();
 }
-
 #endif
 
 void
 geo_rd_deinit(void)
 {
-       if ( cdatastr ) {
-               xfree(cdatastr);
-       }
-       if ( typestr ) {
-               xfree(typestr);
-       }
-       fclose(fd);
+       xml_deinit();
 }
 
 void
@@ -287,6 +198,7 @@ geo_write(void)
 
 ff_vecs_t geo_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        geo_rd_init,    
        geo_wr_init,    
        geo_rd_deinit,
index 60f955c70b3f3b6790ab2d3e70d907bf4572aacb..7fb0d4a7dc43630278e980c8d535fd647dde07d8 100644 (file)
@@ -43,7 +43,7 @@ arglist_t Args[] = {
            "Database name (filename)", NULL, ARGTYPE_STRING },
        {"category", &Arg_category,
            "Category name (Cache)", NULL, ARGTYPE_STRING },
-       {0, 0, 0, 0 }
+       {0, 0, 0, 0, 0 }
 };
 
 #define        ARG_FREE(X) do { if (X) { xfree(X); X = NULL; } } while (0)
@@ -216,7 +216,7 @@ data_read(void)
        char            gid[6+1];
        struct tm       tm;
 
-       wpt = xcalloc(sizeof(*wpt), 1);
+       wpt = waypt_new();
        if (!wpt)
            fatal(MYNAME ": Couldn't allocate waypoint.\n");
        vdata = (char *) pdb_rec->data;
@@ -335,7 +335,7 @@ data_read(void)
        wpt->longitude = lon;
        wpt->altitude = alt;
        wpt->icon_descr = category;
-       wpt->icon_descr_is_dynamic = 1;
+       wpt->wpt_flags.icon_descr_is_dynamic = 1;
 
        if (gid[0])
        {
@@ -484,7 +484,7 @@ copilot_writewpt(const waypoint *wpt)
            fatal(MYNAME ": libpdb couldn't get record memory\n");
     }
 
-    opdb_rec = new_Record (0, 0, ct++, vlen+1, vdata);        
+    opdb_rec = new_Record (0, 0, ct++, (uword) (vlen+1), vdata);              
 
     if (opdb_rec == NULL)
        fatal(MYNAME ": libpdb couldn't create record\n");
@@ -526,6 +526,7 @@ data_write(void)
 ff_vecs_t geoniche_vecs =
 {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
diff --git a/glogbook.c b/glogbook.c
new file mode 100644 (file)
index 0000000..3fe9816
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+    Access Garmin Logbook (Forerunner/Foretracker) data files.
+
+    Copyright (C) 2004 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include "xmlgeneric.h"
+
+static FILE *ofd;
+static waypoint *wpt_tmp;
+static route_head *trk_head;
+
+
+#define MYNAME "glogbook"
+
+static
+arglist_t glogbook_args[] = {
+       {0, 0, 0, 0, 0}
+};
+
+/* Tracks */
+static xg_callback     gl_trk_s;
+// static xg_callback  gl_trk_ident;
+static xg_callback     gl_trk_pnt_s, gl_trk_pnt_e;
+static xg_callback     gl_trk_utc;
+static xg_callback     gl_trk_lat;
+static xg_callback     gl_trk_long;
+static xg_callback     gl_trk_alt;
+
+static xg_tag_mapping gl_map[] = {
+ { gl_trk_s,    cb_start, "/History/Run/Track" },
+ { gl_trk_pnt_s,cb_start, "/History/Run/Track/Trackpoint/Position" },
+ { gl_trk_pnt_e,cb_end,   "/History/Run/Track/Trackpoint/Position" },
+ { gl_trk_lat,  cb_cdata, "/History/Run/Track/Trackpoint/Position/Latitude" },
+ { gl_trk_long, cb_cdata, "/History/Run/Track/Trackpoint/Position/Longitude" },
+ { gl_trk_alt,  cb_cdata, "/History/Run/Track/Trackpoint/Position/Altitude" },
+ { gl_trk_utc,  cb_cdata, "/History/Run/Track/Trackpoint/Time" },
+ { NULL,       0,         NULL}
+};
+
+void
+glogbook_rd_init(const char *fname)
+{
+       xml_init(fname, gl_map);
+}
+
+void
+glogbook_read(void)
+{
+       xml_read();
+}
+
+void
+glogbook_rd_deinit(void)
+{
+       xml_deinit();
+}
+
+void
+glogbook_wr_init(const char *fname)
+{
+        ofd = xfopen(fname, "w", MYNAME);
+}
+
+void
+glogbook_wr_deinit(void)
+{
+        fclose(ofd);
+}
+
+static void
+glogbook_waypt_pr(const waypoint *wpt)
+{      
+       fprintf(ofd, "<Trackpoint>\n");
+       fprintf(ofd, "\t<Position>\n");
+       fprintf(ofd, "\t<Latitude>%f</Latitude>\n", wpt->latitude);
+       fprintf(ofd, "\t<Longitude>%f</Longitude>\n", wpt->longitude);
+       if (wpt->altitude != unknown_alt) {
+               fprintf(ofd, "\t<Altitude>%f</Altitude>\n", wpt->altitude);
+       }
+       xml_write_time(ofd, wpt->creation_time, "Time");
+       fprintf(ofd, "\t</Position>\n");
+       fprintf(ofd, "</Trackpoint>\n");
+}
+
+void
+glogbook_hdr( const route_head *rte)
+{
+       fprintf(ofd, "<Track>\n");
+}
+
+void
+glogbook_ftr(const route_head *rte)
+{
+       fprintf(ofd, "</Track>\n");
+}
+
+void
+glogbook_write(void)
+{
+       fprintf(ofd, "<History xmlns=\"http://www.garmin.com/xmlschemas/ForerunnerLogbook\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.garmin.com/xmlschemas/ForerunnerLogbook http://www.garmin.com/xmlschemas/ForerunnerLogbookv1.xsd\" version=\"1\">\n");
+       fprintf(ofd, "<Run>\n");
+       track_disp_all(glogbook_hdr, glogbook_ftr, glogbook_waypt_pr);
+       fprintf(ofd, "</Run>\n");
+       fprintf(ofd, "</History>\n");
+}
+
+void   gl_trk_s(const char *args, const char **unused)
+{
+       trk_head = route_head_alloc();
+       track_add_head(trk_head);
+}
+#if 0
+void   gl_trk_ident(const char *args, const char **unused)
+{
+       trk_head->rte_name = xstrdup(args);
+}
+#endif
+
+void   gl_trk_pnt_s(const char *args, const char **unused)
+{
+       wpt_tmp = waypt_new();
+}
+
+void   gl_trk_pnt_e(const char *args, const char **unused)
+{
+       route_add_wpt(trk_head, wpt_tmp);
+}
+
+void   gl_trk_utc(const char *args, const char **unused)
+{
+       wpt_tmp->creation_time = xml_parse_time(args);
+}
+
+void   gl_trk_lat(const char *args, const char **unused)
+{
+       wpt_tmp->latitude = atof(args);
+}
+
+void   gl_trk_long(const char *args, const char **unused)
+{
+       wpt_tmp->longitude = atof(args);
+}
+
+void   gl_trk_alt(const char *args, const char **unused)
+{
+       wpt_tmp->altitude = atof(args);
+}
+
+
+
+ff_vecs_t glogbook_vecs = {
+        ff_type_file,
+       FF_CAP_RW_ALL,
+        glogbook_rd_init,
+        glogbook_wr_init,
+        glogbook_rd_deinit,
+        glogbook_wr_deinit,
+        glogbook_read,
+        glogbook_write,
+        NULL,
+        glogbook_args
+};
+
diff --git a/google.c b/google.c
new file mode 100644 (file)
index 0000000..200f3d2
--- /dev/null
+++ b/google.c
@@ -0,0 +1,213 @@
+/* 
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+#include "defs.h"
+#include "xmlgeneric.h"
+
+static char *encoded_points = NULL;
+static char *encoded_levels = NULL;
+static char *script = NULL;
+
+FILE *fd;
+
+static int serial = 0;
+
+#define MYNAME "google"
+#define MY_CBUF 4096
+
+#if NO_EXPAT
+void
+google_rd_init(const char *fname)
+{
+       fatal(MYNAME ": This build excluded Google Maps support because expat was not installed.\n");
+}
+
+void
+google_read(void)
+{
+}
+#else
+
+static xg_callback      goog_points, goog_levels, goog_poly_e, goog_script;
+
+static 
+xg_tag_mapping google_map[] = {
+       { goog_points,  cb_cdata,       "/page/directions/polyline/points" },
+       { goog_levels,  cb_cdata,       "/page/directions/polyline/levels" },
+       { goog_poly_e,  cb_end,         "/page/directions/polyline" },
+       { goog_script,  cb_cdata,       "/html/head/script" },
+       { NULL,         0,              NULL }
+};
+
+void goog_script( const char *args, const char **unused ) 
+{
+       if (args)
+       {
+               if ( script ) 
+               {
+                       script = xstrappend( script, args );
+               }
+               else
+               {
+                       script = xstrdup( args );
+               }
+       }
+}                      
+
+void goog_points( const char *args, const char **unused )
+{
+       if (args)  
+       {
+               if ( encoded_points )
+               {
+                       encoded_points = xstrappend( encoded_points, args );
+               }
+               else 
+               {
+                       encoded_points = xstrdup(args);
+               }
+       }
+}
+
+void goog_levels( const char *args, const char **unused )
+{
+       if (args)  
+       {
+               if ( encoded_levels )
+               {
+                       encoded_levels = xstrappend( encoded_levels, args );
+               }
+               else 
+               {
+                       encoded_levels = xstrdup(args);
+               }
+       }
+}
+
+static long decode_goog64( char **str )
+{
+       long result = 0;
+       unsigned char c = 0;
+       unsigned char shift = 0;
+       
+       do 
+       {
+               c = (unsigned char)(*(*str)++)-'?';
+               result |= (c & 31)<<shift;
+               shift += 5;
+       } while ( c & ~31 );
+       
+       if ( result & 1 ) 
+       {
+               result = ~result;
+       }
+       return result/2;
+}
+
+void goog_poly_e( const char *args, const char **unused )
+{
+       long lat = 0;
+       long lon = 0;
+       long level = 0;
+        char *str = encoded_points;
+       char *lstr = encoded_levels;
+       
+       route_head *track_head = route_head_alloc();
+       route_add_head(track_head);
+
+       while ( str && *str ) 
+       {
+               lat += decode_goog64( &str );
+               lon += decode_goog64( &str );
+               
+               level = 0;
+               if ( lstr && *lstr ) 
+               {
+                       level = decode_goog64( &lstr );
+               } 
+
+               {
+                       waypoint *wpt_tmp = waypt_new();
+                       wpt_tmp->latitude = lat / 100000.0;
+                       wpt_tmp->longitude = lon / 100000.0;
+                       wpt_tmp->route_priority=level;
+                       wpt_tmp->shortname = (char *) xmalloc(7);
+                       sprintf( wpt_tmp->shortname, "\\%5.5x", serial++ );
+                       route_add_wpt(track_head, wpt_tmp);
+               }
+       }
+       
+       if ( encoded_points ) 
+       {
+               xfree( encoded_points );
+               encoded_points = NULL;
+       }
+       if ( encoded_levels )
+       {
+               xfree( encoded_levels );
+               encoded_levels = NULL;
+       }
+}
+
+void
+google_rd_init(const char *fname)
+{
+       xml_init(fname, google_map);
+}
+
+void
+google_read(void)
+{
+       xml_read();
+       if ( script ) 
+       {
+               char *xml = strchr( script, '\'' );
+               char *end = NULL;
+               if ( xml ) {
+                       xml++;
+                       end = strrchr( xml, '\'' );
+                       if ( end ) {
+                               *end = '\0';
+                               xml_deinit();
+                               xml_init( NULL, google_map );
+                               xml_readstring( xml );
+                       }
+               }
+               xfree( script );
+       }
+}
+#endif
+
+void
+google_rd_deinit(void)
+{
+       xml_deinit();
+}
+
+ff_vecs_t google_vecs = {
+       ff_type_file,
+        { ff_cap_none, ff_cap_read, ff_cap_none},
+       google_rd_init, 
+       NULL,
+       google_rd_deinit,
+       NULL,
+       google_read,
+       NULL,
+       NULL, 
+       NULL
+};
index 0a95644fbeaa041d310c23ab95bc8aaaca09e0f6..6af407510b8e5b460d2af6124dad69a2f9f4ba1e 100644 (file)
--- a/gpilots.c
+++ b/gpilots.c
@@ -232,7 +232,11 @@ data_read(void)
                int lon;
                int sz;
                fi_t fi;
-                
+               int trk_num = 0;
+               int trk_seg_num = 1;
+               char trk_seg_num_buf[10];
+               char *trk_name = "";
+
                wpt_tmp = waypt_new();
 
                rec = (struct record *) pdb_rec->data;
@@ -273,7 +277,7 @@ data_read(void)
                          wpt_tmp->depth = fi.f;
                          fi.i = le_read32(&rec->wpt.d108.dist);
                          wpt_tmp->proximity = fi.f;
-                         wpt_tmp->icon_descr_is_dynamic = 0;
+                         wpt_tmp->wpt_flags.icon_descr_is_dynamic = 0;
                          wpt_tmp->icon_descr = mps_find_desc_from_icon_number((rec->wpt.d108.smbl[1] << 8) + rec->wpt.d108.smbl[0], PCX);
                          waypt_add(wpt_tmp);
                          break;
@@ -282,9 +286,7 @@ data_read(void)
                         * CustomTrkHdr
                         */
                        case 101:
-                         track_head = route_head_alloc();
-                         track_add_head(track_head);
-                         track_head->rte_name = xstrndup(rec->wpt.CustTrkHdr.name, sizeof(rec->wpt.CustTrkHdr.name));
+                         trk_name = rec->wpt.CustTrkHdr.name;
                          sz = be_read16(&rec->wpt.CustTrkHdr.number);
               
                          /* switch between custom track points and compact track points.
@@ -294,7 +296,27 @@ data_read(void)
                          case 102:
                                tp_cust = (Custom_Trk_Point_Type *) ((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr));
                                while (sz--) {
+                                 if ((int)(tp_cust->new_trk) == 1 || trk_seg_num == 1) {
+                                       /* 
+                                        * Start a new track segment
+                                        */
+                                       track_head = route_head_alloc();
+                                       if (trk_seg_num == 1) {
+                                         track_head->rte_name = xstrdup(trk_name);
+                                       } else {
+                                         /* name in the form TRACKNAME #n */
+                                         snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num);
+                                         track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3);
+                                         sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf);
+                                       }
+                                       trk_seg_num++;
+                                       track_head->rte_num = trk_num;
+                                       trk_num++;
+                                       track_add_head(track_head);
+                                 }
+
                                  wpt_tmp = waypt_new();
+
                                  /* This is even more odd.
                                   * Track data is stored as big endian while
                                   * waypoint data is little endian!?
@@ -318,6 +340,25 @@ data_read(void)
                          case 104:
                                tp_comp = (Compact_Trk_Point_Type *) ((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr));
                                while (sz--) {
+                                 if ((int)(tp_comp->new_trk) == 1 || trk_seg_num == 1) {
+                                       /* 
+                                        * Start a new track segment
+                                        */
+                                       track_head = route_head_alloc();
+                                       if (trk_seg_num == 1) {
+                                         track_head->rte_name = xstrdup(trk_name);
+                                       } else {
+                                         /* name in the form TRACKNAME #n */
+                                         snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num);
+                                         track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3);
+                                         sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf);
+                                       }
+                                       trk_seg_num++;
+                                       track_head->rte_num = trk_num;
+                                       trk_num++;
+                                       track_add_head(track_head);
+                                 }
+
                                  wpt_tmp = waypt_new();
                                  lon = be_read32(&tp_comp->lon);
                                  lat = be_read32(&tp_comp->lat);
@@ -364,7 +405,7 @@ my_write_wpt(const waypoint *wpt)
        le_write32(&rec->wpt.d103.lat, lat);
        le_write32(&rec->wpt.d103.lon, lon);
 
-       opdb_rec = new_Record(0, 0, ct++, vdata - (char *) rec, (const ubyte *) rec);
+       opdb_rec = new_Record(0, 0, ct++, (uword) (vdata - (char *) rec), (const ubyte *) rec);
 
        if (opdb_rec == NULL) {
                fatal(MYNAME ": libpdb couldn't create record\n");
@@ -408,6 +449,7 @@ data_write(void)
 
 ff_vecs_t gpilots_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
index 7863af855d9ed0d813b8a4f3f657de8a8a07d52a..712b0e39230adbf328ff9709edb0167646b4d6d1 100644 (file)
@@ -122,7 +122,7 @@ data_read(void)
                waypoint *wpt_tmp;
                char *vdata;
 
-               wpt_tmp = xcalloc(sizeof(*wpt_tmp),1);
+               wpt_tmp = waypt_new();
 
                rec = (struct record *) pdb_rec->data;
                wpt_tmp->longitude = be_read32(&rec->longitude) / 3.6e6; 
@@ -207,7 +207,7 @@ gpspilot_writewpt(const waypoint *wpt)
         }
         vdata += strlen( vdata ) + 1;
 
-        opdb_rec = new_Record (0, 2, ct++, vdata-(char *)rec, (const ubyte *)rec);            
+        opdb_rec = new_Record (0, 2, ct++, (uword) (vdata-(char *)rec), (const ubyte *)rec);          
 
        if (opdb_rec == NULL) {
                fatal(MYNAME ": libpdb couldn't create record\n");
@@ -247,6 +247,7 @@ data_write(void)
 
 ff_vecs_t gpspilot_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
index eeec5659f1f12d57c3dbc5ea0efa23e28d476861..ae648d093f08cb95ba6adbc88a7dd747517e50b0 100644 (file)
--- a/gpsutil.c
+++ b/gpsutil.c
@@ -84,7 +84,7 @@ data_read(void)
                sscanf(&ibuf[70], "%2c", icon);
                rtrim(desc);
                rtrim(icon);
-               wpt_tmp = xcalloc(sizeof(*wpt_tmp),1);
+               wpt_tmp = waypt_new();
                wpt_tmp->altitude = alt;
                wpt_tmp->shortname = xstrdup(name);
                wpt_tmp->description = xstrdup(desc);
@@ -118,7 +118,7 @@ gpsutil_disp(const waypoint *wpt)
 
        fprintf(file_out, "%-8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n",
                 global_opts.synthesize_shortnames ?
-                        mkshort(mkshort_handle, wpt->description) : 
+                        mkshort_from_wpt(mkshort_handle, wpt) : 
                        wpt->shortname,
                fabs(lat),
                lat < 0.0 ? 'S' : 'N',
@@ -141,6 +141,7 @@ data_write(void)
 
 ff_vecs_t gpsutil_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
diff --git a/gpx.c b/gpx.c
index 7b9830da3743eaac4ac2fbf21d5b1ac39f5e1807..73ef4596ec804a3e666df65e8340705887da1ef8 100644 (file)
--- a/gpx.c
+++ b/gpx.c
@@ -1,7 +1,7 @@
 /*
     Access GPX data files.
 
-    Copyright (C) 2002, 2003, 2004 Robert Lipe, robertlipe@usa.net
+    Copyright (C) 2002, 2003, 2004, 2005 Robert Lipe, robertlipe@usa.net
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
  */
 
 #include "defs.h"
+#include "xmlgeneric.h"
 #ifndef NO_EXPAT
        #include <expat.h>
        static XML_Parser psr;
@@ -31,6 +32,8 @@ static char *opt_logpoint = NULL;
 static int logpoint_ct = 0;
 
 static const char *gpx_version;
+static char *gpx_wversion;
+static int gpx_wversion_num;
 static const char *gpx_creator;
 static char *xsi_schema_loc;
 
@@ -49,7 +52,6 @@ static int input_string_len = 0;
 
 static time_t file_time;
 
-static char *gsshortnames = NULL;
 static char *snlen = NULL;
 static char *suppresswhite = NULL;
 static char *urlbase = NULL;
@@ -59,6 +61,17 @@ static route_head *rte_head;
 #define MYNAME "GPX"
 #define MY_CBUF 4096
 #define DEFAULT_XSI_SCHEMA_LOC "http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd"
+#define DEFAULT_XSI_SCHEMA_LOC_FMT "\"http://www.topografix.com/GPX/%c/%c http://www.topografix.com/GPX/%c/%c/gpx.xsd\""
+
+/* 
+ * Format used for floating point formats.  Put in one place to make it
+ * easier to tweak when comparing output with other GPX programs that 
+ * have more or less digits of output...
+ */
+/* #define FLT_FMT "%.9lf" */  /* ExpertGPS */
+#define FLT_FMT "%0.9lf" 
+#define FLT_FMT_T "%lf" 
+#define FLT_FMT_R "%lf" 
 
 typedef enum {
        tt_unknown = 0,
@@ -77,6 +90,8 @@ typedef enum {
        tt_wpt_time,
        tt_wpt_type,
        tt_wpt_urlname,
+       tt_wpt_link,            /* New in GPX 1.1 */
+       tt_wpt_link_text,       /* New in GPX 1.1 */
        tt_cache,
        tt_cache_name,
        tt_cache_container,
@@ -87,6 +102,9 @@ typedef enum {
        tt_cache_desc_short,
        tt_cache_desc_long,
        tt_cache_log_wpt,
+       tt_cache_log_type,
+       tt_cache_log_date,
+       tt_cache_placer,
        tt_rte,
        tt_rte_name,
        tt_rte_desc,
@@ -145,6 +163,8 @@ tag_mapping tag_path_map[] = {
        { tt_wpt_desc, 0, "/gpx/wpt/desc" },
        { tt_wpt_url, 0, "/gpx/wpt/url" },
        { tt_wpt_urlname, 0, "/gpx/wpt/urlname" },
+       { tt_wpt_link, 0, "/gpx/wpt/link" },                    /* GPX 1.1 */
+       { tt_wpt_link_text, 0, "/gpx/wpt/link/text" },          /* GPX 1.1 */
        { tt_wpt_sym, 0, "/gpx/wpt/sym" },
        { tt_wpt_type, 1, "/gpx/wpt/type" },
        { tt_cache, 1, "/gpx/wpt/groundspeak:cache" },
@@ -157,6 +177,9 @@ tag_mapping tag_path_map[] = {
        { tt_cache_desc_short, 1, "/gpx/wpt/groundspeak:cache/groundspeak:short_description" },
        { tt_cache_desc_long, 1, "/gpx/wpt/groundspeak:cache/groundspeak:long_description" },
        { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt" },
+       { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type" },
+       { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date" },
+       { tt_cache_placer, 1, "/gpx/wpt/groundspeak:cache/groundspeak:owner" },
 
        { tt_rte, 0, "/gpx/rte" },
        { tt_rte_name, 0, "/gpx/rte/name" },
@@ -189,24 +212,6 @@ tag_mapping tag_path_map[] = {
        {0}
 };
 
-
-static void
-write_xml_entity(FILE *ofd, const char *indent, 
-                 const char *tag, const char *value)
-{
-       char *tmp_ent = xml_entitize(value);
-       fprintf(ofd, "%s<%s>%s</%s>\n", indent, tag, tmp_ent, tag);
-       xfree(tmp_ent);
-}
-
-static void
-write_optional_xml_entity(FILE *ofd, const char *indent, 
-                          const char *tag, const char *value)
-{
-       if (value && *value)
-               write_xml_entity(ofd, indent, tag, value);
-}
-
 static tag_type
 get_tag(const char *t, int *passthrough)
 {
@@ -427,6 +432,11 @@ gpx_start(void *data, const char *el, const char **attr)
        case tt_wpt:
                tag_wpt(attr);
                break;
+       case tt_wpt_link:
+               if (0 == strcmp(attr[0], "href")) {
+                       wpt_tmp->url = xstrdup(attr[1]);
+               }
+               break;
        case tt_rte:
                rte_head = route_head_alloc();
                route_add_head(rte_head);
@@ -468,12 +478,18 @@ gs_type_mapping{
        geocache_type type;
        const char *name;
 } gs_type_map[] = {
-       { gt_traditional, "Traditional cache" },
-       { gt_multi, "Multi-Cache" },
-       { gt_virtual, "Virtual cache" },
-       { gt_event, "Event cache" },
+       { gt_traditional, "Traditional Cache" },
+       { gt_multi, "Multi-cache" },
+       { gt_virtual, "Virtual Cache" },
+       { gt_event, "Event Cache" },
        { gt_webcam, "Webcam Cache" },
-       { gt_suprise, "Unknown cache" },
+       { gt_suprise, "Unknown Cache" },
+       { gt_earth, "Earthcache" },
+       { gt_cito, "Cache In Trash Out Event" },
+       { gt_letterbox, "Letterbox Hybrid" },
+       { gt_locationless, "Locationless (Reverse) Cache" },
+
+       { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK  */
 };
 
 struct
@@ -490,7 +506,7 @@ gs_container_mapping{
 };
 
 geocache_type
-gs_mktype(char *t)
+gs_mktype(const char *t)
 {
        int i;
        int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]);
@@ -518,7 +534,7 @@ gs_get_cachetype(geocache_type t)
 }
 
 geocache_container
-gs_mkcont(char *t)
+gs_mkcont(const char *t)
 {
        int i;
        int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]);
@@ -546,7 +562,7 @@ gs_get_container(geocache_container t)
 }
 
 time_t 
-xml_parse_time( char *cdatastr ) 
+xml_parse_time( const char *cdatastr ) 
 {
        int off_hr = 0;
        int off_min = 0;
@@ -613,6 +629,7 @@ gpx_end(void *data, const char *el)
        float x;
        char *cdatastrp = cdatastr.mem;
        int passthrough;
+       static time_t gc_log_date;
 
        if (strcmp(s + 1, el)) {
                fprintf(stderr, "Mismatched tag %s\n", el);
@@ -643,6 +660,7 @@ gpx_end(void *data, const char *el)
                wpt_tmp->url = xstrdup(cdatastrp);
                break;
        case tt_wpt_urlname:
+       case tt_wpt_link_text:
                wpt_tmp->url_link_text = xstrdup(cdatastrp);
                break;
        case tt_wpt:
@@ -652,11 +670,7 @@ gpx_end(void *data, const char *el)
                wpt_tmp = NULL;
                break;
        case tt_cache_name:
-               if (gsshortnames) {
-                       if (wpt_tmp->notes)
-                               xfree(wpt_tmp->notes);
-                       wpt_tmp->notes = xstrdup(cdatastrp);
-               }
+               wpt_tmp->notes = xstrdup(cdatastrp);
                break;
        case tt_cache_container:
                wpt_tmp->gc_data.container = gs_mkcont(cdatastrp);
@@ -692,6 +706,24 @@ gpx_end(void *data, const char *el)
                sscanf(cdatastrp, "%f", &x);
                wpt_tmp->gc_data.terr = x * 10;
                break;
+       case tt_cache_placer:
+               wpt_tmp->gc_data.placer = xstrdup(cdatastrp);
+               break;
+       case tt_cache_log_date:
+               gc_log_date = xml_parse_time( cdatastrp );
+               break;
+       /*
+        * "Found it" logs follow the date according to the schema,
+        * if this is the first "found it" for this waypt, just use the
+        * last date we saw in this log.
+        */
+       case tt_cache_log_type:
+               if ((0 == strcmp(cdatastrp, "Found it")) && 
+                   (0 == wpt_tmp->gc_data.last_found)) {
+                       wpt_tmp->gc_data.last_found  = gc_log_date;
+               }
+               gc_log_date = 0;
+               break;
        /*
         * Route-specific tags.
         */
@@ -744,7 +776,7 @@ gpx_end(void *data, const char *el)
        case tt_rte_rtept_sym:
        case tt_trk_trkseg_trkpt_sym:
                wpt_tmp->icon_descr = xstrdup(cdatastrp);
-               wpt_tmp->icon_descr_is_dynamic = 1;
+               wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1;
                break;
        case tt_wpt_time:
        case tt_trk_trkseg_trkpt_time:
@@ -998,31 +1030,6 @@ gpx_read(void)
 #endif /* NO_EXPAT */
 }
 
-/*
- *
- */
-static
-void
-gpx_write_time(const time_t timep, char *elname)
-{
-       struct tm *tm = gmtime(&timep);
-       
-       if (!tm)
-               return;
-       
-       fprintf(ofd, "<%s>%02d-%02d-%02dT%02d:%02d:%02dZ</%s>\n",
-               elname,
-               tm->tm_year+1900, 
-               tm->tm_mon+1, 
-               tm->tm_mday, 
-               tm->tm_hour, 
-               tm->tm_min, 
-               tm->tm_sec,
-               elname
-       );
-
-}
-
 static void
 fprint_tag_and_attrs( char *prefix, char *suffix, xml_tag *tag )
 {
@@ -1059,7 +1066,7 @@ fprint_xml_chain( xml_tag *tag, const waypoint *wpt )
                        }
                        if ( strcmp(tag->tagname, "groundspeak:cache" ) == 0 
                                        && wpt->gc_data.exported) {
-                               gpx_write_time( wpt->gc_data.exported, 
+                               xml_write_time( ofd, wpt->gc_data.exported, 
                                                "groundspeak:exported" );
                        }
                        fprintf( ofd, "</%s>", tag->tagname);
@@ -1106,10 +1113,36 @@ void free_gpx_extras( xml_tag *tag )
        }
 }
 
+/*
+ * Handle the grossness of GPX 1.0 vs. 1.1 handling of linky links.
+ */
 static void
-gpx_waypt_pr(const waypoint *waypointp)
+write_gpx_url(const waypoint *waypointp)
 {
        char *tmp_ent;
+
+       if (waypointp->url) {
+               tmp_ent = xml_entitize(waypointp->url);
+               if (gpx_wversion_num > 10) {
+                       
+                       fprintf(ofd, "  <link href=\"%s%s\">\n", 
+                               urlbase ? urlbase : "", tmp_ent);
+                       write_optional_xml_entity(ofd, "  ", "text", 
+                               waypointp->url_link_text);
+                       fprintf(ofd, "  </link>\n");
+               } else {
+                       fprintf(ofd, "  <url>%s%s</url>\n", 
+                               urlbase ? urlbase : "", tmp_ent);
+                       write_optional_xml_entity(ofd, "  ", "urlname", 
+                               waypointp->url_link_text);
+               }
+               xfree(tmp_ent);
+       }
+}
+
+static void
+gpx_waypt_pr(const waypoint *waypointp)
+{
        const char *oname;
        char *odesc;
 
@@ -1128,28 +1161,24 @@ gpx_waypt_pr(const waypoint *waypointp)
                                  mkshort(mkshort_handle, odesc) : 
                                  waypointp->shortname;
 
-       fprintf(ofd, "<wpt lat=\"%0.9lf\" lon=\"%0.9lf\">\n",
+       fprintf(ofd, "<wpt lat=\"" FLT_FMT "\" lon=\"" FLT_FMT "\">\n",
                waypointp->latitude,
                waypointp->longitude);
-       if (waypointp->creation_time) {
-               gpx_write_time(waypointp->creation_time, "time");
-       }
        if (waypointp->altitude != unknown_alt) {
                fprintf(ofd, "  <ele>%f</ele>\n",
                         waypointp->altitude);
        }
+       if (waypointp->creation_time) {
+               xml_write_time(ofd, waypointp->creation_time, "time");
+       }
        write_optional_xml_entity(ofd, "  ", "name", oname);
        write_optional_xml_entity(ofd, "  ", "cmt", waypointp->description);
        if (waypointp->notes && waypointp->notes[0])
                write_xml_entity(ofd, "  ", "desc", waypointp->notes);
        else
                write_optional_xml_entity(ofd, "  ", "desc", waypointp->description);
-       if (waypointp->url) {
-               tmp_ent = xml_entitize(waypointp->url);
-               fprintf(ofd, "  <url>%s%s</url>\n", urlbase ? urlbase : "", tmp_ent);
-               xfree(tmp_ent);
-       }
-       write_optional_xml_entity(ofd, "  ", "urlname", waypointp->url_link_text);
+       write_gpx_url(waypointp);
+
        write_optional_xml_entity(ofd, "  ", "sym", waypointp->icon_descr);
 
        fprint_xml_chain( waypointp->gpx_extras, waypointp );
@@ -1171,16 +1200,27 @@ gpx_track_hdr(const route_head *rte)
 static void
 gpx_track_disp(const waypoint *waypointp)
 {
-       fprintf(ofd, "<trkpt lat=\"%lf\" lon=\"%lf\">\n",
+       fprintf(ofd, "<trkpt lat=\"" FLT_FMT_T "\" lon=\"" FLT_FMT_T "\">\n",
                waypointp->latitude,
                waypointp->longitude);
        if (waypointp->altitude != unknown_alt) {
-               fprintf(ofd, "<ele>%f</ele>\n",
+               fprintf(ofd, "  <ele>%f</ele>\n",
                         waypointp->altitude);
        }
        if (waypointp->creation_time) {
-               gpx_write_time(waypointp->creation_time,"time");
+               xml_write_time(ofd, waypointp->creation_time,"time");
+       }
+
+       /* GPX doesn't require a name on output, so if we made one up
+        * on input, we might as well say nothing.
+        */
+       if (!waypointp->wpt_flags.shortname_is_synthetic) {
+               write_optional_xml_entity(ofd, "  ", "name", 
+                       waypointp->shortname);
        }
+       write_optional_xml_entity(ofd, "  ", "desc", waypointp->notes);
+       write_gpx_url(waypointp);
+       write_optional_xml_entity(ofd, "  ", "sym", waypointp->icon_descr);
        fprintf(ofd, "</trkpt>\n");
 }
 
@@ -1211,7 +1251,7 @@ gpx_route_hdr(const route_head *rte)
 static void
 gpx_route_disp(const waypoint *waypointp)
 {
-       fprintf(ofd, "  <rtept lat=\"%f\" lon=\"%f\">\n",
+       fprintf(ofd, "  <rtept lat=\"" FLT_FMT_R "\" lon=\"" FLT_FMT_R "\">\n",
                waypointp->latitude,
                waypointp->longitude);
 
@@ -1220,7 +1260,7 @@ gpx_route_disp(const waypoint *waypointp)
                         waypointp->altitude);
        }
        if (waypointp->creation_time) {
-               gpx_write_time(waypointp->creation_time,"time");
+               xml_write_time(ofd, waypointp->creation_time,"time");
        }
        write_optional_xml_entity(ofd, "    ", "name", waypointp->shortname);
        write_optional_xml_entity(ofd, "    ", "cmt", waypointp->description);
@@ -1248,6 +1288,12 @@ gpx_write(void)
        time_t now = 0;
        int short_length;
        bounds bounds;
+
+       gpx_wversion_num = strtod(gpx_wversion, NULL) * 10;
+
+       if (gpx_wversion_num <= 0) {
+               fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion);
+       }
        
         now = current_time();
 
@@ -1263,13 +1309,23 @@ gpx_write(void)
        setshort_length(mkshort_handle, short_length);
 
        fprintf(ofd, "<?xml version=\"1.0\"?>\n");
-       fprintf(ofd, "<gpx\n version=\"1.0\"\n");
+       fprintf(ofd, "<gpx\n version=\"%s\"\n", gpx_wversion);
        fprintf(ofd, "creator=\"GPSBabel - http://www.gpsbabel.org\"\n");
        fprintf(ofd, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
-       fprintf(ofd, "xmlns=\"http://www.topografix.com/GPX/1/0\"\n");
-       fprintf(ofd, "xsi:schemaLocation=\"%s\">\n", xsi_schema_loc ? xsi_schema_loc : DEFAULT_XSI_SCHEMA_LOC);
+       fprintf(ofd, "xmlns=\"http://www.topografix.com/GPX/%c/%c\"\n", gpx_wversion[0], gpx_wversion[2]);
+       if (xsi_schema_loc) {
+               fprintf(ofd, "xsi:schemaLocation=\"%s\">\n", xsi_schema_loc);
+       } else {
+               fprintf(ofd,
+                       "xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n",
+                       gpx_wversion[0], gpx_wversion[2],
+                       gpx_wversion[0], gpx_wversion[2]);
+       }
 
-       gpx_write_time( now, "time" );
+       if (gpx_wversion_num > 10) {    
+               fprintf(ofd, "<metadata>\n");
+       }
+       xml_write_time( ofd, now, "time" );
        waypt_compute_bounds(&bounds);
        if (bounds.max_lat  > -360) {
                fprintf(ofd, "<bounds minlat=\"%0.9f\" minlon =\"%0.9f\" "
@@ -1277,18 +1333,20 @@ gpx_write(void)
                               bounds.min_lat, bounds.min_lon, 
                               bounds.max_lat, bounds.max_lon);
        }
+
+       if (gpx_wversion_num > 10) {    
+               fprintf(ofd, "</metadata>\n");
+       }
+
        waypt_disp_all(gpx_waypt_pr);
-       gpx_track_pr();
        gpx_route_pr();
+       gpx_track_pr();
 
        fprintf(ofd, "</gpx>\n");
 }
 
 static
 arglist_t gpx_args[] = {
-       { "gsshortnames", &gsshortnames, 
-               "Prefer shorter descriptions from Groundspeak files",
-               NULL, ARGTYPE_BOOL },
        { "snlen", &snlen, "Length of generated shortnames", 
                NULL, ARGTYPE_INT },
        { "suppresswhite", &suppresswhite, 
@@ -1299,11 +1357,14 @@ arglist_t gpx_args[] = {
                NULL, ARGTYPE_BOOL },
        { "urlbase", &urlbase, "Base URL for link tag in output", 
                NULL, ARGTYPE_STRING},
+       { "gpxver", &gpx_wversion, "Target GPX version for output", 
+               "1.0", ARGTYPE_STRING},
        { 0, 0, 0, 0, 0 }
 };
 
 ff_vecs_t gpx_vecs = {
        ff_type_file,
+       FF_CAP_RW_ALL,
        gpx_rd_init,    
        gpx_wr_init,    
        gpx_rd_deinit,  
diff --git a/gpxval b/gpxval
index 2447c1d2f781ae7e093fee5d8688bcce36c0de6c..98e6947701c8d86be8b9482bdbe6d4e6b4518198 100644 (file)
--- a/gpxval
+++ b/gpxval
@@ -1,8 +1,32 @@
 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/robertl/xerces-c1_7_0-linux7.2/lib
 export PATH=$PATH:/home/robertl/xerces-c1_7_0-linux7.2/bin
 
+gpxval()
+{
+       echo "Validating $*"
+       ./gpsbabel $* -o gpx -F /tmp/$$.gpx
+       SAX2Count /tmp/$$.gpx
+       ./gpsbabel $* -o gpx,gpxver=1.0 -F /tmp/$$.gpx
+       SAX2Count /tmp/$$.gpx
+       ./gpsbabel $* -o gpx,gpxver=1.1 -F /tmp/$$.gpx
+       SAX2Count /tmp/$$.gpx
+}
+
+
+# gpxval "-i gpx -f reference/holux.gpx" 
+gpxval -i mapsend -f reference/chicago.trk
+
 SAX2Count reference/holux.gpx
-./gpsbabel -i gpx -f reference/holux.gpx -o gpx -F /tmp/1.gpx
-SAX2Count /tmp/1.gpx
-./gpsbabel -i mapsend -f reference/chicago.trk -o gpx -F /tmp/2.gpx
-SAX2Count /tmp/2.gpx
+
+# Routes
+
+# gpxval -i gpx -f reference/route/blah.gpx 
+gpxval -i magellan -f reference/route/magellan.rte 
+gpxval -i psitrex -f reference/route/psitrtes.txt 
+# gpxval -i gpx -f reference/route/route.gpx 
+gpxval -i mapsend -f reference/route/route.mapsend 
+gpxval -i mapsource -f reference/route/route.mps 
+
+# Tracks
+
+gpxval -i mapsource -f reference/route/route.mps 
diff --git a/hiketech.c b/hiketech.c
new file mode 100644 (file)
index 0000000..a1d0264
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+    Access Hiketech XML data files.
+
+    Copyright (C) 2004,2005 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include "xmlgeneric.h"
+
+static FILE *ofd;
+static waypoint *wpt_tmp;
+static route_head *trk_head;
+
+
+#define MYNAME "hiketech"
+
+static
+arglist_t hiketech_args[] = {
+       {0, 0, 0, 0, 0}
+};
+
+/* Waypoints */
+static xg_callback     ht_wpt_s;
+static xg_callback     ht_wpt_e;
+static xg_callback     ht_ident;
+static xg_callback     ht_sym;
+static xg_callback     ht_lat;
+static xg_callback     ht_long;
+static xg_callback     ht_alt;
+
+/* Tracks */
+static xg_callback     ht_trk_s, ht_trk_e;
+static xg_callback     ht_trk_ident;
+static xg_callback     ht_trk_pnt_s, ht_trk_pnt_e;
+static xg_callback     ht_trk_utc;
+static xg_callback     ht_trk_lat;
+static xg_callback     ht_trk_long;
+static xg_callback     ht_trk_alt;
+
+static xg_tag_mapping ht_map[] = {
+       { ht_wpt_s,     cb_start, "/hiketech/gpsdata/wpt" },
+       { ht_wpt_e,     cb_end,   "/hiketech/gpsdata/wpt" },
+       { ht_ident,     cb_cdata, "/hiketech/gpsdata/wpt/ident" },
+       { ht_sym,       cb_cdata, "/hiketech/gpsdata/wpt/sym" },
+       { ht_lat,       cb_cdata, "/hiketech/gpsdata/wpt/lat" },
+       { ht_long,      cb_cdata, "/hiketech/gpsdata/wpt/long" },
+       { ht_alt,       cb_cdata, "/hiketech/gpsdata/wpt/alt" },
+
+       { ht_trk_s,     cb_start, "/hiketech/gpsdata/trk" },
+       { ht_trk_e,     cb_end,   "/hiketech/gpsdata/trk" },
+       { ht_trk_ident, cb_cdata, "/hiketech/gpsdata/trk/ident" },
+       { ht_trk_pnt_s, cb_start, "/hiketech/gpsdata/trk/pnt" },
+       { ht_trk_pnt_e, cb_end,   "/hiketech/gpsdata/trk/pnt" },
+       { ht_trk_utc,   cb_cdata, "/hiketech/gpsdata/trk/pnt/utc" },
+       { ht_trk_lat,   cb_cdata, "/hiketech/gpsdata/trk/pnt/lat" },
+       { ht_trk_long,  cb_cdata, "/hiketech/gpsdata/trk/pnt/long" },
+       { ht_trk_alt,   cb_cdata, "/hiketech/gpsdata/trk/pnt/alt" },
+       { NULL,         0,         NULL}
+};
+
+void
+hiketech_rd_init(const char *fname)
+{
+       xml_init(fname, ht_map);
+}
+
+void
+hiketech_read(void)
+{
+       xml_read();
+}
+
+void
+hiketech_rd_deinit(void)
+{
+}
+
+void
+hiketech_wr_init(const char *fname)
+{
+        ofd = xfopen(fname, "w", MYNAME);
+}
+
+void
+hiketech_wr_deinit(void)
+{
+        fclose(ofd);
+}
+
+static void
+hiketech_trk_hdr(const route_head *rte)
+{
+       fprintf(ofd, "<trk>\n");
+       write_optional_xml_entity(ofd, " ", "ident", rte->rte_name);
+}
+
+static void
+hiketech_trk_tlr(const route_head *rte)
+{
+       fprintf(ofd, "</trk>\n");
+}
+
+void
+hiketech_print_utc(time_t tm, const char *indent, const char *tag)
+{
+       char tbuf[80];
+        strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %I:%M:%S", gmtime(&tm));
+       fprintf(ofd, "%s<%s>%s</%s>\n",indent,tag,tbuf,tag);
+}
+
+static void
+hiketech_trkpt_pr(const waypoint *waypointp)
+{
+       fprintf(ofd, " <pnt>\n");
+       if (waypointp->creation_time) {
+               hiketech_print_utc(waypointp->creation_time, "  ", "utc");
+       }
+       fprintf(ofd, "  <lat>%f</lat>\n", waypointp->latitude);
+       fprintf(ofd, "  <long>%f</long>\n", waypointp->longitude);
+       if (waypointp->altitude != unknown_alt) {
+               fprintf(ofd, "  <alt>%f</alt>\n",
+                        waypointp->altitude);
+       }
+       fprintf(ofd, " </pnt>\n");
+}
+
+static void
+hiketech_waypt_pr(const waypoint *wpt)
+{      
+       fprintf(ofd, "<wpt>\n");
+       write_xml_entity(ofd, "\t", "ident", wpt->shortname);
+       write_optional_xml_entity(ofd, "\t", "sym", wpt->icon_descr);
+       fprintf(ofd, "\t<lat>%f</lat>\n", wpt->latitude);
+       fprintf(ofd, "\t<long>%f</long>\n", wpt->longitude);
+
+       /* 
+        * These probably aren't technicallyconstants, but it's all 
+        * we can do for now. 
+        */
+       fprintf(ofd, "\t<color>\n\t\t<lbl>FAFFB4</lbl>\n\t\t<obj>FF8000</obj>\n\t</color>\n");
+       fprintf(ofd, "</wpt>\n");
+}
+
+void
+hiketech_write(void)
+{
+       fprintf(ofd, "<hiketech version=\"1.2\" url=\"http://www.hiketech.com\">\n");
+       fprintf(ofd, "<gpsdata>\n");
+       track_disp_all(hiketech_trk_hdr, hiketech_trk_tlr, hiketech_trkpt_pr);
+       track_disp_all(NULL, NULL, hiketech_trkpt_pr);
+       waypt_disp_all(hiketech_waypt_pr);
+       fprintf(ofd, "</gpsdata>\n");
+       fprintf(ofd, "</hiketech>\n");
+}
+
+void    ht_wpt_s(const char *args, const char **unused)
+{
+       wpt_tmp = waypt_new();
+}
+
+void   ht_ident(const char *args, const char **unused)
+{
+       wpt_tmp->shortname = xstrdup(args);
+}
+
+void   ht_sym(const char *args, const char **unused)
+{
+       wpt_tmp->icon_descr = xstrdup(args);
+       wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1;
+}
+
+void   ht_lat(const char *args, const char **unused)
+{
+       wpt_tmp->latitude = atof(args);
+}
+
+void   ht_long(const char *args, const char **unused)
+{
+       wpt_tmp->longitude = atof(args);
+}
+
+void   ht_alt(const char *args, const char **unused)
+{
+       wpt_tmp->altitude = atof(args);
+}
+
+void   ht_wpt_e(const char *args, const char **unused)
+{
+       waypt_add(wpt_tmp);
+       wpt_tmp = NULL;
+}
+
+void   ht_trk_s(const char *args, const char **unused)
+{
+       trk_head = route_head_alloc();
+       track_add_head(trk_head);
+}
+
+void   ht_trk_e(const char *args, const char **unused)
+{
+
+}
+
+void   ht_trk_ident(const char *args, const char **unused)
+{
+       trk_head->rte_name = xstrdup(args);
+}
+
+void   ht_trk_pnt_s(const char *args, const char **unused)
+{
+       wpt_tmp = waypt_new();
+}
+
+void   ht_trk_pnt_e(const char *args, const char **unused)
+{
+       route_add_wpt(trk_head, wpt_tmp);
+}
+
+void   ht_trk_utc(const char *args, const char **unused)
+{
+       struct tm tm;
+       time_t utc;
+
+       sscanf(args, "%d-%d-%d %d:%d:%d",
+               &tm.tm_year, &tm.tm_mon,
+               &tm.tm_mday, &tm.tm_hour,
+               &tm.tm_min, &tm.tm_sec);
+        tm.tm_mon -= 1;
+        tm.tm_year -= 1900;
+        tm.tm_isdst = 0;
+
+        utc = mktime(&tm) + get_tz_offset() ;
+
+       wpt_tmp->creation_time = utc;
+}
+
+void   ht_trk_lat(const char *args, const char **unused)
+{
+       wpt_tmp->latitude = atof(args);
+}
+
+void   ht_trk_long(const char *args, const char **unused)
+{
+       wpt_tmp->longitude = atof(args);
+}
+
+void   ht_trk_alt(const char *args, const char **unused)
+{
+       wpt_tmp->altitude = atof(args);
+}
+
+
+
+ff_vecs_t hiketech_vecs = {
+        ff_type_file,
+       { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write },
+        hiketech_rd_init,
+        hiketech_wr_init,
+        hiketech_rd_deinit,
+        hiketech_wr_deinit,
+        hiketech_read,
+        hiketech_write,
+        NULL,
+        hiketech_args
+};
+
diff --git a/holux.c b/holux.c
index 41735b2d4c9fc070f14d60a3b73eb2aa8723cd25..03613ff7f6a11c16c5b8549af89425e31fc6d9fe 100644 (file)
--- a/holux.c
+++ b/holux.c
@@ -106,7 +106,7 @@ static void data_read(void)
     /* Get the waypoints */
     for (iCount = 0; iCount < iWptNum ; iCount ++)
     {
-        wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
+        wpt_tmp = waypt_new();
     
        iWptIndex = le_read16(&((WPTHDR *)HxWpt)->idx[iCount]);
         pWptHxTmp =  (WPT *)&HxWpt[OFFS_WPT + (sizeof(WPT) * iWptIndex)];
@@ -291,6 +291,7 @@ static void data_write(void)
 
 ff_vecs_t holux_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
index 7cfa2c66d4963e34477562ef6d2ed93fd8477580..d52452048e8ec683de29f1598eba3098f3227537 100644 (file)
--- a/hsa_ndv.c
+++ b/hsa_ndv.c
@@ -309,9 +309,8 @@ hsa_ndv_waypt_pr(const waypoint *waypointp)
 //     fprintf(ofd, "\t\t\t<FeatureNameAgency>0</FeatureNameAgency>\n");
 //     fprintf(ofd, "\t\t\t<FeatureNameSubDiv>1</FeatureNameSubDiv>\n");
 //     fprintf(ofd, "\t\t\t<FeatureNameNumber>1089009023</FeatureNameNumber>\n");
-       fprintf(ofd, "\t\t\t<Attr>attr=grpnam%s\x1ftrnrad50\x1fOBJNAM%s\x1flegnum%i\x1fusrmrk%s\x1fselect2\1f</Attr>\n",
-                               routeName, waypointp->shortname, legNum, waypointp->description);
-       fprintf(ofd, "\t\t\t<LegAttr>attr=grpnam%s\x1f</LegAttr>\n", routeName);
+       fprintf(ofd, "\t\t\t<Attr><![CDATA[attr=grpnam%s\x1ftrnrad50\x1fOBJNAM%s\x1flegnum%i\x1fusrmrk%s\x1fselect2\1f]]></Attr>\n", routeName, waypointp->shortname, legNum, waypointp->description);
+       fprintf(ofd, "\t\t\t<LegAttr><![CDATA[attr=grpnam%s\x1f]]></LegAttr>\n", routeName);
        fprintf(ofd, "\t\t\t<NumberOfVertexs>1</NumberOfVertexs>\n");
        fprintf(ofd, "\t\t\t<Latitude>%lf</Latitude>\n", waypointp->latitude);
        fprintf(ofd, "\t\t\t<Longitude>%lf</Longitude>\n", waypointp->longitude);
@@ -345,6 +344,7 @@ hsa_ndv_write(void)
 
 ff_vecs_t HsaEndeavourNavigator_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        hsa_ndv_rd_init,        
        hsa_ndv_wr_init,        
        hsa_ndv_rd_deinit,
diff --git a/html.c b/html.c
index bc00b547e75e89c62f832d5f643576d4e39b932e..ab72d1c4980cd92184be5b0b248615a8a5ebdb41 100644 (file)
--- a/html.c
+++ b/html.c
@@ -66,12 +66,12 @@ html_disp(const waypoint *wpt)
        int latint, lonint;
        char tbuf[1024];
        time_t tm = wpt->creation_time;
-       long utmz;
+       int32 utmz;
        double utme, utmn;
        char utmzc;
        
-       lonint = abs(wpt->longitude);
-       latint = abs(wpt->latitude);
+       lonint = abs((int) wpt->longitude);
+       latint = abs((int) wpt->latitude);
        GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, 
                &utme, &utmn, &utmz, &utmzc);
 
@@ -83,7 +83,7 @@ html_disp(const waypoint *wpt)
        fprintf(file_out, "<hr>\n");
        fprintf(file_out, "<a name=\"%s\"></a><table width=\"100%%\"><tr><td>\n", wpt->shortname);
        fprintf(file_out, "<h3 class=\"waypoint\">%s - %c%d&deg;%06.3f %c%d&deg;%06.3f (%ld%c %6.0f %7.0f)",
-               (global_opts.synthesize_shortnames) ? mkshort(mkshort_handle, wpt->description) : wpt->shortname,
+               (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname,
                wpt->latitude < 0 ? 'S' : 'N',  latint, 60.0 * (fabs(wpt->latitude) - latint), 
                wpt->longitude < 0 ? 'W' : 'E', lonint, 60.0 * (fabs(wpt->longitude) - lonint),
                utmz, utmzc, utme, utmn);
@@ -104,10 +104,14 @@ html_disp(const waypoint *wpt)
        }
        if (wpt->gc_data.terr) {
                if (wpt->gc_data.desc_short.utfstring) {
-                       fprintf (file_out, "<p class=\"descshort\">%s</p>\n", strip_nastyhtml(wpt->gc_data.desc_short.utfstring));
+                       char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_short.utfstring);
+                       fprintf (file_out, "<p class=\"descshort\">%s</p>\n", tmpstr );
+                       xfree( tmpstr );
                        }
                if (wpt->gc_data.desc_long.utfstring) {
-                       fprintf (file_out, "<p class=\"desclong\">%s</p>\n", strip_nastyhtml(wpt->gc_data.desc_long.utfstring));
+                       char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_long.utfstring);
+                       fprintf (file_out, "<p class=\"desclong\">%s</p>\n", tmpstr );
+                       xfree( tmpstr );
                        }
                if (wpt->gc_data.hint) {
                        char *hint = NULL;
@@ -254,6 +258,7 @@ data_write(void)
 
 ff_vecs_t html_vecs = {
        ff_type_file,
+       { ff_cap_write, ff_cap_none, ff_cap_none },
        NULL,
        wr_init,
        NULL,
diff --git a/igc.c b/igc.c
index 5ccbfb0c6c169a926c9fe3d4dcd9d6ac077990e9..188e7d3783ee84dd1eb02bc159575145fc9b4543 100644 (file)
--- a/igc.c
+++ b/igc.c
@@ -518,8 +518,8 @@ static char *latlon2str(const waypoint * wpt)
     char lon_hemi = wpt->longitude < 0 ? 'W' : 'E';
     unsigned char lat_deg = fabs(wpt->latitude);
     unsigned char lon_deg = fabs(wpt->longitude);
-    unsigned int lat_min = (fabs(wpt->latitude) - lat_deg) * 60000 + 0.5;
-    unsigned int lon_min = (fabs(wpt->longitude) - lon_deg) * 60000 + 0.5;
+    unsigned int lat_min = (fabs(wpt->latitude) - lat_deg) * 60000 + 0.500000000001;
+    unsigned int lon_min = (fabs(wpt->longitude) - lon_deg) * 60000 + 0.500000000001;
 
     if (snprintf(str, 18, "%02u%05u%c%03u%05u%c",
                 lat_deg, lat_min, lat_hemi, lon_deg, lon_min, lon_hemi) != 17) {
@@ -842,20 +842,20 @@ static void wr_track(void)
        QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) {
            wpt = (waypoint *) elem;
            pres_alt = interpolate_alt(pres_track, wpt->creation_time + time_adj);
-           wr_fix_record(wpt, pres_alt, wpt->altitude);
+           wr_fix_record(wpt, (int) pres_alt, (int) wpt->altitude);
        }
     } else {
        if (pres_track) {
            // Only the pressure altitude track was found so generate fix
            // records from it alone.
            QUEUE_FOR_EACH(&pres_track->waypoint_list, elem, tmp) {
-               wr_fix_record((waypoint *) elem, ((waypoint *) elem)->altitude, unknown_alt);
+               wr_fix_record((waypoint *) elem, (int) ((waypoint *) elem)->altitude, (int) unknown_alt);
            }
        } else if (gnss_track) {
            // Only the GNSS altitude track was found so generate fix
            // records from it alone.
            QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) {
-               wr_fix_record((waypoint *) elem, unknown_alt, ((waypoint *) elem)->altitude);
+               wr_fix_record((waypoint *) elem, (int) unknown_alt, (int) ((waypoint *) elem)->altitude);
            }
        } else {
            // No tracks found so nothing to do
@@ -894,6 +894,7 @@ static arglist_t igc_args[] = {
 
 ff_vecs_t igc_vecs = {
     ff_type_file,
+    { ff_cap_none , ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write },
     rd_init,
     wr_init,
     rd_deinit,
diff --git a/intdoc/GPSBabel Windows GUI 2.00.00 Project Plan.pdf b/intdoc/GPSBabel Windows GUI 2.00.00 Project Plan.pdf
new file mode 100644 (file)
index 0000000..2dc7865
Binary files /dev/null and b/intdoc/GPSBabel Windows GUI 2.00.00 Project Plan.pdf differ
diff --git a/intdoc/SA2003_an1_dump.pl b/intdoc/SA2003_an1_dump.pl
new file mode 100644 (file)
index 0000000..5bbb690
--- /dev/null
@@ -0,0 +1,200 @@
+#!/usr/bin/perl
+
+=pod
+
+  This script reads a DeLorme Street Atlas 2003 .an1 (drawing) file 
+  and prints various pertinent data from it.  Anything with a variable 
+  name starting with "unk" or "magic" or "zero" is probably something 
+  we don't yet understand.  Suggestions as to what some of these fields 
+  mean are welcome.  The author disclaims any liability arising from 
+  the use of any information contained within this script. 
+
+    Copyright (C) 2005 Ronald L. Parker (babelan1perl@parkrrrr.com)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+=cut
+
+# Convert a longword to a latitude or longitude
+sub decode {
+   my $foo = shift;
+
+   my $deg = (0x80000000-$foo)/(0x800000);
+   sprintf( "%d %06.3f", $deg, 60*($deg-int($deg)));
+}
+
+
+# read a data structure from the input file.  
+sub shiftunpack {
+
+   my $pattern = shift;
+   my @result = unpack( $pattern, $file );
+   my $str = pack( $pattern, @result );
+   $file = substr( $file, length( $str ));
+   @result;
+}
+
+sub skip_bytes {
+   my $count = shift;
+   $file = substr( $file, $count );
+}
+
+sub decodeGuid {
+   ($a, $b, $c, $d, $e, $f, $g, $h, $i, $j) = unpack( 'LSSSCCCCCC', shift );
+   sprintf( '%8.8x-%4.4x-%4.4x-%4.4x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x',$a, $b, $c, $d, $e, $f, $g, $h, $i, $j);
+}
+
+# read file
+undef $/;
+$file = <>;
+
+@filetypes = qw( drawing road trail waypoint track );
+
+# read file header
+($magic, $filetype ) = shiftunpack( 'ss' );
+
+print <<END;
+MAGIC   $magic
+$filetypes[$filetype] layer
+
+END
+
+# read bitmap info
+($bitmapcount) = shiftunpack( 'l' );
+
+while ( $bitmapcount ) {
+  ($rec_type) = shiftunpack( 's' );
+  if ( $rec_type == 0x4c49 ) { # 'IL'
+    # I don't know what this structure is, but it appears twice in my test files.
+    ($unk10101, $unke, $unkc, $unk18_1, $unk18_2, $unkneg1_1,
+     $unk20, $unkneg1_2, $unkneg1_3) = shiftunpack( 'lsssslsll');
+  }
+  elsif ( $rec_type == 0x4d42 ) { # 'BM'
+    # This is a standard BMP file, documented in MSDN.
+    # BITMAPFILEHEADER
+    ($fhsize, $res_0_1, $res_0_2, $bitoffset) = shiftunpack( 'lssl' );
+    # BITMAPINFOHEADER
+    ($bmisize, $width, $height, $planes, $bpp, $compression, 
+     $size, $xppm, $yppm, $colused, $colimprt ) = shiftunpack( 'lllssllllll');
+    # palette
+    $palettesize = $bitoffset - $bmisize - 14; # 14 bytes in BMFH, including the 'BM'
+
+    open BMP, ">bitmap$filecount.bmp";
+    binmode BMP;
+    print BMP 'BM';
+    $head = pack('lssl', ($fhsize,  $res_0_1, $res_0_2, $bitoffset));
+    print BMP $head;
+    $head = pack('lllssllllll', ($bmisize, $width, $height, $planes, $bpp,
+            $compression, $size, $xppm, $yppm, $colused, $colimprt));
+    print BMP $head;
+    print BMP substr($file, 0, $palettesize+$size);
+    close BMP;
+    $filecount++;
+
+    skip_bytes( $palettesize );
+    # image
+    skip_bytes( $size );
+  }
+  else {
+    # image information - the 'type' we read was actually the low word of the hotspot X coord.
+    ($hotspotxhi, $hotspoty, $unk1, $guid, $name ) = shiftunpack( 'slla[16]C/a*' );
+
+    # fix the hotspot X coord
+    $hotspotx = $rec_type + 0x10000*$hotspotxhi;
+
+    printf( "Image: %2d %2d %s $name\n", $hotspotx, $hotspoty, decodeGuid( $guid ) );
+    $imagenames{$guid} = $name;
+    $bitmapcount--; 
+  }
+} 
+
+# waypoint information
+
+($magic, $wptcount) = shiftunpack( 'sl' );
+
+@types = qw(none marker line polygon text circle mapnote highlight unknown8 arc spline rectangle
+         unknown12 unknown13 road trail track waypoint);
+
+print( "$wptcount waypoints\n" );
+while ( $wptcount ) {
+
+  ($magic, $unk1, $lon, $lat, $type, $height, $width, $unk2, $unk3, $serial, 
+   $unk4, $create_zoom, $visible_zoom, $unk5, $circle_radius, $name, $font, 
+   $guid, $fontcolor, $fontstyle, $fontsize, $unk6, $outlinecolor, $unk7, 
+   $fillcolor, $unk8, $unk9 ) = 
+   shiftunpack( 'slllsllssssCCsds/a*s/a*a[16]lllllllll' );
+
+   # fontcolor is BGR (i.e. pure blue is 0xff00000, pure red is 0x0000ff)
+   # fontstyle is 0x10-bold, 0x20-italic, 0x80-underline
+
+   # width/height are in pixels for mapnotes and represent the offset of the mapnote
+   #    from the point (i.e. the dimensions of the tail.)
+   # width/height are in degrees times 0x800000 for rectangles
+
+   # Note that type appears to be shared with lines.
+   # type   desc
+   #   1     marker (flag, dot, etc.)
+   #   4     text
+   #   5     circle
+   #   6     mapnote
+   #  11     rectangle
+   #  17     waypoint
+
+  $lat = decode( $lat );
+  $lon = decode( $lon );
+
+  $rect_height = $height/0x800000;
+  $rect_width = $width/0x800000;
+
+  printf ( "$magic -- %x %x %x %x %x %x %x %x %x -- $type $types[$type]  $lat  $lon  %s $imagenames{$guid}  '$name'\n", 
+      $unk1,  $unk2,  $unk3,  $unk4,  $unk5,  $unk6,  $unk7, $unk8, $unk9, decodeGuid( $guid ) );
+
+  $wptcount--;
+} 
+
+# line information
+($magic, $linecount ) = shiftunpack( 'sl' );
+print ( "$linecount lines\n" );
+while ( $linecount ) {
+  ($magic, $unk1, $serial, $unk2, $unk3, $type, $unk4, $name, $lineweight, $linestyle, 
+   $linecolor, $unk5, $polyfillcolor, $unk6, $unk7, $unk8, $pointcount ) = 
+    shiftunpack( 'ssslssls/a*sllllllsl' );
+
+   # arcs are 4-point (3-segment) lines: start, third point, end, center (yes, that's overdetermined.)
+
+   # Note that type appears to be shared with points.
+   # type   desc
+   #   2     line
+   #   3     polygon
+   #   7     highlight
+   #   9     arc
+   #  10     spline
+   #  14     routable road
+   #  15     trail
+   #  16     track
+
+   printf ("--- start line ---   %.4x  %x %x %x %x %x %x %x %x -- $type $types[$type] '$name'\n", $magic,
+               $unk1, $unk2, $unk3, $unk4, $unk5, $unk6, $unk7, $unk8 );
+  while ( $pointcount ) {
+    ($magic, $unk0, $lon, $lat, $unk0s ) = shiftunpack( 'sllls' );
+    $lat = decode( $lat );
+    $lon = decode( $lon );
+    printf (" $magic   $lat   $lon   %x %x\n", $unk0, $unk0s);
+    $pointcount--;
+  }
+  print "--- end line ---\n";
+  $linecount--;
+}
+
index 3b31cde74cc652d48745f9181c6c01b98b348337..49efddea315c37b08e97a7b10e9645c0828a3741 100644 (file)
@@ -27,7 +27,7 @@ static char arc[] =
 static char csv[] = 
 "# gpsbabel XCSV style file\n"
 "#\n"
-"# Format: Delorme SA 9.0 CSV\n"
+"# Format: DeLorme SA 9.0 CSV\n"
 "# Author: Alex Mottram\n"
 "#   Date: 12/09/2002\n"
 "#\n"
@@ -45,9 +45,13 @@ static char csv[] =
 "#\n"
 "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n"
 "#\n"
-"IFIELD        LAT_DECIMAL, \"\", \"%08.5f\"\n"
-"IFIELD        LON_DECIMAL, \"\", \"%08.5f\"\n"
+"IFIELD        LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n"
+"IFIELD        LON_HUMAN_READABLE, \"\", \"%08.5f\"\n"
 "IFIELD        DESCRIPTION, \"\", \"%s\"\n"
+
+"OFIELD        LAT_DECIMAL, \"\", \"%08.5f\"\n"
+"OFIELD        LON_DECIMAL, \"\", \"%08.5f\"\n"
+"OFIELD        DESCRIPTION, \"\", \"%s\"\n"
 ;
 static char custom[] = 
 "# gpsbabel XCSV style file\n"
@@ -384,16 +388,16 @@ static char s_and_t[] =
 "# GC171C,44.70605,-85.62265,The Michigan Frog by RealDcoy & LRB,http://www.geocaching.com/seek/cache_details.aspx?ID=5916,Traditional Cache\n"
 "#\n"
 
-"DESCRIPTION           Microsoft Streets and Trips 2002/2003\n"
+"DESCRIPTION           Microsoft Streets and Trips 2002-2005\n"
 
 "#\n"
 "# FILE LAYOUT DEFINITIIONS:\n"
 "#\n"
-"FIELD_DELIMITER               COMMA\n"
+"FIELD_DELIMITER               TAB\n"
 "RECORD_DELIMITER      NEWLINE\n"
 "BADCHARS              ,\"\n"
 
-"PROLOGUE      Name,Latitude,Longitude,Name 2,URL,Type\n"
+"PROLOGUE      Name    Latitude        Longitude       Description     URL     Type    Container       Diff    Terr\n"
 
 "#\n"
 "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n"
@@ -405,7 +409,10 @@ static char s_and_t[] =
 "IFIELD        LON_DECIMAL, \"\", \"%f\"               # Longitude\n"
 "IFIELD        DESCRIPTION, \"\", \"%s\"               # Name 2 (Big Description)\n"
 "IFIELD        URL, \"\", \"%s\"                       # URL\n"
-"IFIELD        IGNORE, \"\", \"\"                      # Holder for Geocache Type\n"
+"IFIELD        GEOCACHE_TYPE, \"\", \"%s\"             # Geocache Type\n"
+"IFIELD        GEOCACHE_CONTAINER, \"\", \"%s\"        # Geocache Type\n"
+"IFIELD        GEOCACHE_DIFF, \"\", \"%3.1f\"  # Geocache Type\n"
+"IFIELD        GEOCACHE_TERR, \"\", \"%3.1f\"  # Geocache Type\n"
 ;
 static char saplus[] = 
 "# gpsbabel XCSV style file\n"
@@ -415,7 +422,7 @@ static char saplus[] =
 "#   Date: 02/22/04\n"
 "#\n"
 
-"DESCRIPTION             Delorme Street Atlas Plus\n"
+"DESCRIPTION             DeLorme Street Atlas Plus\n"
 
 "#\n"
 "# FILE LAYOUT DEFINITIIONS:\n"
@@ -491,11 +498,13 @@ static char tabsep[] =
 "IFIELD  GEOCACHE_TYPE,\"\",\"%s\"\n"
 "IFIELD  PATH_DISTANCE_MILES,\"\",\"%f\"\n"
 "IFIELD  PATH_DISTANCE_KM, \"\", \"%f\"\n"
+"IFIELD  GEOCACHE_PLACER,\"\",\"%s\"\n"
+"IFIELD  YYYYMMDD_TIME,\"\",\"%ld\"\n"
 ;
 static char xmap[] = 
 "# gpsbabel XCSV style file\n"
 "#\n"
-"# Format: Delorme Xmap Conduit\n"
+"# Format: DeLorme Xmap Conduit\n"
 "# Author: Alex Mottram\n"
 "#   Date: 12/09/2002\n"
 "#\n"
@@ -503,7 +512,7 @@ static char xmap[] =
 "# As defined in csv.c/xmap\n"
 "#\n"
 
-"DESCRIPTION           Delorme XMap HH Native .WPT\n"
+"DESCRIPTION           DeLorme XMap HH Native .WPT\n"
 "EXTENSION             wpt\n"
 
 "#\n"
@@ -518,19 +527,23 @@ static char xmap[] =
 "#\n"
 "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n"
 "#\n"
-"IFIELD        LAT_DECIMAL, \"\", \"%08.5f\"\n"
-"IFIELD        LON_DECIMAL, \"\", \"%08.5f\"\n"
+"IFIELD        LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n"
+"IFIELD        LON_HUMAN_READABLE, \"\", \"%08.5f\"\n"
 "IFIELD        DESCRIPTION, \"\", \"%s\"\n"
+
+"OFIELD        LAT_DECIMAL, \"\", \"%08.5f\"\n"
+"OFIELD        LON_DECIMAL, \"\", \"%08.5f\"\n"
+"OFIELD        DESCRIPTION, \"\", \"%s\"\n"
 ;
 static char xmapwpt[] = 
 "# gpsbabel XCSV style file\n"
 "#\n"
-"# Format: Delorme Xmap HH Street Atlas USA .WPT (PocketPC)\n"
+"# Format: DeLorme Xmap HH Street Atlas USA .WPT (PocketPC)\n"
 "# Author: Alex Mottram\n"
 "#   Date: 12/09/2002\n"
 "#\n"
 "# \n"
-"DESCRIPTION           Delorme XMat HH Street Atlas USA .WPT (PPC)\n"
+"DESCRIPTION           DeLorme XMat HH Street Atlas USA .WPT (PPC)\n"
 "SHORTLEN              32\n"
 "SHORTWHITE            0\n"
 
index 2c6f0c1965f01be7be7a264064339a08d6e1ba12..69dba75aacdf68d14c4e98fa756961f0e0c25bb2 100644 (file)
@@ -149,6 +149,9 @@ typedef struct GPS_SWay
     int32  rte_link_class;
     char   rte_link_subclass[18];
     char   rte_link_ident[256];
+
+    char     Time_populated;   /* 1 if true */
+    time_t   Time;             /* Unix time */
 } GPS_OWay, *GPS_PWay;
 
 
@@ -179,7 +182,6 @@ extern double gps_save_version;
 extern char   gps_save_string[GPS_ARB_LEN];
 extern int gps_is_usb;
 
-
 extern struct COMMANDDATA COMMAND_ID[2];
 extern struct LINKDATA LINK_ID[3];
 extern struct GPS_MODEL_PROTOCOL GPS_MP[];
@@ -190,7 +192,6 @@ extern char *gps_aviation_sym[];
 extern char *gps_16_sym[];
 
 
-
 #endif
 
 #ifdef __cplusplus
index 2db5a4df8e0f10136d697445f9b66c3e14c70f47..4648457532512a64b961fd35a5795784d52f991b 100644 (file)
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <time.h>
 #include <stdlib.h>
+#include <ctype.h>
 
 #define XMIN(a,b) (a < b? a : b)
 
@@ -48,7 +49,7 @@ static void   GPS_D105_Get(GPS_PWay *way, UC *s);
 static void   GPS_D106_Get(GPS_PWay *way, UC *s);
 static void   GPS_D107_Get(GPS_PWay *way, UC *s);
 static void   GPS_D108_Get(GPS_PWay *way, UC *s);
-static void   GPS_D109_Get(GPS_PWay *way, UC *s);
+static void   GPS_D109_Get(GPS_PWay *way, UC *s, int proto);
 static void   GPS_D150_Get(GPS_PWay *way, UC *s);
 static void   GPS_D151_Get(GPS_PWay *way, UC *s);
 static void   GPS_D152_Get(GPS_PWay *way, UC *s);
@@ -64,7 +65,7 @@ static void   GPS_D105_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D106_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D107_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D108_Send(UC *data, GPS_PWay way, int32 *len);
-static void   GPS_D109_Send(UC *data, GPS_PWay way, int32 *len);
+static void   GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int proto);
 static void   GPS_D150_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D151_Send(UC *data, GPS_PWay way, int32 *len);
 static void   GPS_D152_Send(UC *data, GPS_PWay way, int32 *len);
@@ -102,6 +103,30 @@ int        gps_is_usb;
 double gps_save_version;
 char   gps_save_string[GPS_ARB_LEN];
 
+/*
+ * Internal function to copy what Garmin describes as a "Character Array".
+ * Dest buffer is padded with spaces and must not contain nulls.  Optionally
+ * we uppercase the string because some models (III's and 12's) react
+ * violently to lower case data.
+ */
+typedef enum { UpperNo = 0, UpperYes = 1 } copycase;
+static 
+void copy_char_array(UC **dst, UC* src, int count, copycase mustupper)
+{
+       UC *d = *dst;
+       int ocount =  count;
+       do {
+               UC sc = *src++;
+               if (sc == 0) {
+                       while (count--) 
+                               *d++ = ' ';
+                       break;
+               }
+               else *d++ = mustupper == UpperYes ? toupper(sc) : sc;
+       } while (--count) ;
+       *dst += ocount;
+}
+
 
 /* @func GPS_Init ******************************************************
 **
@@ -319,10 +344,9 @@ static void GPS_A001(GPS_PPacket packet)
            }
            else if(data<200)
            {
-               if(data!=100)
-                   GPS_Protocol_Error(tag,data);
-               else
+               if(data==100)
                    gps_waypt_transfer = pA100;
+               /* Ignore A101 Waypoint Category Transfer Protocol. */
                continue;
            }
            else if(data<300)
@@ -415,7 +439,7 @@ static void GPS_A001(GPS_PPacket packet)
        {
            if(lasta<200)
            {
-               if(data<=109 && data>=100)
+               if(data<=110 && data>=100)
                {
                    gps_waypt_type = data;
                    continue;
@@ -430,6 +454,11 @@ static void GPS_A001(GPS_PPacket packet)
                    gps_waypt_type = data;
                    continue;
                }
+               if (data == 120) 
+               {
+                       /* Quest 3.0 has a D120  for Wpt category ignore it*/
+                       continue;
+               }
                else
                    GPS_Protocol_Error(tag,data);
            }
@@ -448,7 +477,7 @@ static void GPS_A001(GPS_PPacket packet)
                    continue;
                }
                    
-               if(data<=109 && data>=100)
+               if(data<=110 && data>=100)
                {
                    gps_rte_type = data;
                    continue;
@@ -588,7 +617,7 @@ static void GPS_A001(GPS_PPacket packet)
 **
 ** @return [int32] number of waypoint entries
 ************************************************************************/
-int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)())
+int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *))
 {
     static UC data[2];
     int32 fd;
@@ -672,7 +701,10 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)())
            GPS_D108_Get(&((*way)[i]),rec->data);
            break;
        case pD109:
-           GPS_D109_Get(&((*way)[i]),rec->data);
+           GPS_D109_Get(&((*way)[i]),rec->data, 109);
+           break;
+       case pD110:
+           GPS_D109_Get(&((*way)[i]),rec->data, 110);
            break;
        case pD150:
            GPS_D150_Get(&((*way)[i]),rec->data);
@@ -739,7 +771,7 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)())
 **
 ** @return [int32] success
 ************************************************************************/
-int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)())
+int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *))
 {
     UC data[GPS_ARB_LEN];
     int32 fd;
@@ -754,7 +786,7 @@ int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)())
     if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New()))
        return MEMORY_ERROR;
 
-    GPS_Util_Put_Short(data,n);
+    GPS_Util_Put_Short(data, (short) n);
     GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records,
                    data,2);
     if(!GPS_Write_Packet(fd,tra))
@@ -769,7 +801,7 @@ int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)())
     for(i=0;i<n;++i)
     {
         if (cb) {
-               if (cb(way[i]))
+               if (cb((GPS_PWay *) way[i]))  /* BUGBUG Wrong level of indirection */
                        break;
        }
 
@@ -803,7 +835,10 @@ int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)())
            GPS_D108_Send(data,way[i],&len);
            break;
        case pD109:
-           GPS_D109_Send(data,way[i],&len);
+           GPS_D109_Send(data,way[i],&len, 109);
+           break;
+       case pD110:
+           GPS_D109_Send(data,way[i],&len, 110);
            break;
        case pD150:
            GPS_D150_Send(data,way[i],&len);
@@ -826,7 +861,7 @@ int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)())
        }
 
        GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Wpt_Data,
-                       data,len);
+                  data, (US) len);
 
        if(!GPS_Write_Packet(fd,tra))
            return gps_errno;
@@ -1208,9 +1243,9 @@ static void GPS_D108_Get(GPS_PWay *way, UC *s)
     
     (*way)->alt = GPS_Util_Get_Float(p);
     p+=sizeof(float);
-    (*way)->dpth = (int32)GPS_Util_Get_Float(p);
+    (*way)->dpth = GPS_Util_Get_Float(p);
     p+=sizeof(float);
-    (*way)->dst = (int32)GPS_Util_Get_Float(p);
+    (*way)->dst = GPS_Util_Get_Float(p);
     p+=sizeof(float);
 
     for(i=0;i<2;++i) (*way)->state[i] = *p++;
@@ -1245,8 +1280,11 @@ static void GPS_D108_Get(GPS_PWay *way, UC *s)
 ** @param [r] s [UC *] packet data
 **
 ** @return [void]
+** Quest uses D110's which are just like D109's but with the addition
+** of temp, time, and wpt_cat stuck between ete and ident.   Rather than
+** duplicating the function, we just handle this at runtime.
 ************************************************************************/
-static void GPS_D109_Get(GPS_PWay *way, UC *s)
+static void GPS_D109_Get(GPS_PWay *way, UC *s, int protoid)
 {
     UC *p;
     UC *q;
@@ -1272,15 +1310,20 @@ static void GPS_D109_Get(GPS_PWay *way, UC *s)
     
     (*way)->alt = GPS_Util_Get_Float(p);
     p+=sizeof(float);
-    (*way)->dpth = (int32)GPS_Util_Get_Float(p);
+    (*way)->dpth = GPS_Util_Get_Float(p);
     p+=sizeof(float);
-    (*way)->dst = (int32)GPS_Util_Get_Float(p);
+    (*way)->dst = GPS_Util_Get_Float(p);
     p+=sizeof(float);
 
     for(i=0;i<2;++i) (*way)->state[i] = *p++;
     for(i=0;i<2;++i) (*way)->cc[i] = *p++;
 
     p += 4; /* Skip over "outbound link ete in seconds */
+    if (protoid == 110) {
+       p += 4; /* skip float temp */
+       p += 4;  /* skip longword time */
+       p += 2; /* skip int "category membership " */
+    }
 
     q = (UC *) (*way)->ident;
     while((*q++ = *p++));
@@ -1562,18 +1605,17 @@ static void GPS_D155_Get(GPS_PWay *way, UC *s)
 static void GPS_D100_Send(UC *data, GPS_PWay way, int32 *len)
 {
     UC *p;
-    int32 i;
     
     p = data;
 
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+    copy_char_array(&p, way->ident, 6, UpperYes);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
     p+=sizeof(int32);
     GPS_Util_Put_Uint(p,0);
     p+=sizeof(int32);
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
 
     *len = 58;
     
@@ -1594,18 +1636,18 @@ static void GPS_D100_Send(UC *data, GPS_PWay way, int32 *len)
 static void GPS_D101_Send(UC *data, GPS_PWay way, int32 *len)
 {
     UC *p;
-    int32 i;
     
     p = data;
 
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+    copy_char_array(&p, way->ident, 6, UpperYes);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
     p+=sizeof(int32);
     GPS_Util_Put_Uint(p,0);
     p+=sizeof(int32);
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
+
 
     GPS_Util_Put_Float(p,way->dst);
     p+= sizeof(float);
@@ -1631,23 +1673,22 @@ static void GPS_D101_Send(UC *data, GPS_PWay way, int32 *len)
 static void GPS_D102_Send(UC *data, GPS_PWay way, int32 *len)
 {
     UC *p;
-    int32 i;
     
     p = data;
 
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+    copy_char_array(&p, way->ident, 6, UpperYes);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
     p+=sizeof(int32);
     GPS_Util_Put_Uint(p,0);
     p+=sizeof(int32);
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
 
     GPS_Util_Put_Float(p,way->dst);
     p+= sizeof(float);
 
-    GPS_Util_Put_Short(p,way->smbl);
+    GPS_Util_Put_Short(p,(US) way->smbl);
     
     *len = 64;
     
@@ -1668,18 +1709,10 @@ static void GPS_D102_Send(UC *data, GPS_PWay way, int32 *len)
 static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len)
 {
     UC *p;
-    int32 i;
     
     p = data;
 
-    for(i=0;i<6;++i)  {
-           if (way->ident[i] == 0) {
-                   memset(p, ' ', 6-i);
-                   p+=6-i;
-                   break;
-           }
-           *p++ = way->ident[i];
-    }
+    copy_char_array(&p, way->ident, 6, UpperYes);
 
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
@@ -1687,10 +1720,10 @@ static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len)
     p+=sizeof(int32);
     GPS_Util_Put_Uint(p,0);
     p+=sizeof(int32);
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
 
-    *p++ = way->smbl;
-    *p   = way->dspl;
+    *p++ = (UC) way->smbl;
+    *p   = (UC) way->dspl;
     
     *len = 60;
     
@@ -1711,11 +1744,10 @@ static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len)
 static void GPS_D104_Send(UC *data, GPS_PWay way, int32 *len)
 {
     UC *p;
-    int32 i;
     
     p = data;
 
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+    copy_char_array(&p, way->ident, 6, UpperYes);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
@@ -1726,12 +1758,12 @@ static void GPS_D104_Send(UC *data, GPS_PWay way, int32 *len)
      * results in the comment being truncated there.   So we uppercase
      * the entire comment.
      */
-    for(i=0;i<40;++i) *p++ = toupper(way->cmnt[i]);
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
 
     GPS_Util_Put_Float(p,way->dst);
     p+= sizeof(float);
 
-    GPS_Util_Put_Short(p,way->smbl);
+    GPS_Util_Put_Short(p, (int16) way->smbl);
     p+=sizeof(int16);
 
     *p = 3; /* display symbol with waypoint name */
@@ -1764,7 +1796,7 @@ static void GPS_D105_Send(UC *data, GPS_PWay way, int32 *len)
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
     p+=sizeof(int32);
 
-    GPS_Util_Put_Short(p,way->smbl);
+    GPS_Util_Put_Short(p, (int16) way->smbl);
     p+=sizeof(int16);
 
     q = (UC *) way->wpt_ident;
@@ -1802,7 +1834,7 @@ static void GPS_D106_Send(UC *data, GPS_PWay way, int32 *len)
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
     p+=sizeof(int32);
 
-    GPS_Util_Put_Short(p,way->smbl);
+    GPS_Util_Put_Short(p, (int16) way->smbl);
     p+=sizeof(int16);
 
     q = (UC *) way->wpt_ident;
@@ -1829,17 +1861,17 @@ static void GPS_D106_Send(UC *data, GPS_PWay way, int32 *len)
 static void GPS_D107_Send(UC *data, GPS_PWay way, int32 *len)
 {
     UC *p;
-    int32 i;
     
     p = data;
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+
+    copy_char_array(&p, way->ident, 6, UpperYes);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
     p+=sizeof(int32);
     GPS_Util_Put_Uint(p,0);
     p+=sizeof(int32);
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
 
     *p++ = way->smbl;
     *p++ = way->dspl;
@@ -1879,7 +1911,7 @@ static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len)
     *p++ = way->colour;
     *p++ = way->dspl;
     *p++ = 0x60;
-    GPS_Util_Put_Short(p,way->smbl);
+    GPS_Util_Put_Short(p,(US) way->smbl);
     p+=sizeof(int16);
     for(i=0;i<18;++i) *p++ = way->subclass[i];
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
@@ -1932,8 +1964,9 @@ static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len)
 ** @param [w] len [int32 *] packet length
 **
 ** @return [void]
+** D109's and D110's are so simlar, we handle themw with the same code.
 ************************************************************************/
-static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len)
+static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int protoid)
 {
     UC *p;
     UC *q;
@@ -1945,8 +1978,14 @@ static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len)
     *p++ = 0 /* way->colour*/ ;                /* If non-zero, the waypoint is in 
                                           invisible ink on the V. */
     *p++ = way->dspl;
-    *p++ = 0x70;
-    GPS_Util_Put_Short(p,way->smbl);
+    if (protoid == 109) {
+       *p++ = 0x70;
+    } else if (protoid == 110) {
+       *p++  = 0x80;
+    } else {
+       GPS_Warning("Unknown protoid in GPS_D109_Send.");
+    }
+    GPS_Util_Put_Short(p,(US) way->smbl);
     p+=sizeof(int16);
     for(i=0;i<18;++i) *p++ = way->subclass[i];
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
@@ -1963,6 +2002,21 @@ static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len)
     for(i=0;i<2;++i) *p++ = way->state[i];
     for(i=0;i<2;++i) *p++ = way->cc[i];
     for(i=0;i<4;++i) *p++ = 0xff; /* D109 silliness for ETE */
+    if (protoid == 110) {
+       float temp = 1.0e25f;
+
+       GPS_Util_Put_Float(p, temp);
+       p += 4;
+
+       if (way->Time_populated) {
+               GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(way->Time));
+               p+=sizeof(uint32);
+       } else {
+               for(i=0;i<4;++i) *p++ = 0xff; /* unknown time*/
+       }
+
+       for(i=0;i<2;++i) *p++ = 0x00; /* D110 category */
+    }
 
     q = (UC *) way->ident;
     i = XMIN(51, sizeof(way->ident));
@@ -2004,7 +2058,7 @@ static void GPS_D150_Send(UC *data, GPS_PWay way, int32 *len)
 
     p = data;
 
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+    copy_char_array(&p, way->ident, 6, UpperYes);
     for(i=0;i<2;++i) *p++ = way->cc[i];
 
     if(way->wpt_class == 7) way->wpt_class = 0;
@@ -2015,13 +2069,13 @@ static void GPS_D150_Send(UC *data, GPS_PWay way, int32 *len)
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
     p+=sizeof(int32);
 
-    GPS_Util_Put_Short(p,way->alt);
+    GPS_Util_Put_Short(p,(US) way->alt);
     p+=sizeof(int16);
 
-    for(i=0;i<24;++i) *p++ = way->city[i];
-    for(i=0;i<2;++i)  *p++ = way->state[i];
-    for(i=0;i<30;++i) *p++ = way->name[i];
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];
+    copy_char_array(&p, way->city, 24, UpperYes);
+    copy_char_array(&p, way->state, 2, UpperYes);
+    copy_char_array(&p, way->name, 30, UpperYes);
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
 
     *len = 115;
 
@@ -2046,7 +2100,7 @@ static void GPS_D151_Send(UC *data, GPS_PWay way, int32 *len)
     
     p = data;
 
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+    copy_char_array(&p, way->ident, 6, UpperYes);
     
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
@@ -2054,15 +2108,15 @@ static void GPS_D151_Send(UC *data, GPS_PWay way, int32 *len)
     p+=sizeof(int32);
     GPS_Util_Put_Uint(p,0);
     p+=sizeof(int32);
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];    
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
     GPS_Util_Put_Float(p,way->dst);
     p+=sizeof(float);
 
-    for(i=0;i<30;++i) *p++ = way->name[i];
-    for(i=0;i<24;++i) *p++ = way->city[i];
-    for(i=0;i<2;++i)  *p++ = way->state[i];
+    copy_char_array(&p, way->name, 30, UpperYes);
+    copy_char_array(&p, way->city, 24, UpperYes);
+    copy_char_array(&p, way->state, 2, UpperYes);
 
-    GPS_Util_Put_Short(p,way->alt);
+    GPS_Util_Put_Short(p,(US) way->alt);
     p+=sizeof(int16);
 
     for(i=0;i<2;++i) *p++ = way->cc[i];
@@ -2095,7 +2149,7 @@ static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len)
     
     p = data;
 
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+    copy_char_array(&p, way->ident, 6, UpperYes);
     
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
@@ -2103,15 +2157,15 @@ static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len)
     p+=sizeof(int32);
     GPS_Util_Put_Uint(p,0);
     p+=sizeof(int32);
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];    
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
     GPS_Util_Put_Float(p,way->dst);
     p+=sizeof(float);
 
-    for(i=0;i<30;++i) *p++ = way->name[i];
-    for(i=0;i<24;++i) *p++ = way->city[i];
-    for(i=0;i<2;++i)  *p++ = way->state[i];
+    copy_char_array(&p, way->name, 30, UpperYes);
+    copy_char_array(&p, way->city, 24, UpperYes);
+    copy_char_array(&p, way->state, 2, UpperYes);
 
-    GPS_Util_Put_Short(p,way->alt);
+    GPS_Util_Put_Short(p,(US) way->alt);
     p+=sizeof(int16);
 
     for(i=0;i<2;++i) *p++ = way->cc[i];
@@ -2143,7 +2197,7 @@ static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len)
     
     p = data;
 
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+    copy_char_array(&p, way->ident, 6, UpperYes);
     
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
@@ -2151,15 +2205,16 @@ static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len)
     p+=sizeof(int32);
     GPS_Util_Put_Uint(p,0);
     p+=sizeof(int32);
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];    
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
+
     GPS_Util_Put_Float(p,way->dst);
     p+=sizeof(float);
 
-    for(i=0;i<30;++i) *p++ = way->name[i];
-    for(i=0;i<24;++i) *p++ = way->city[i];
-    for(i=0;i<2;++i)  *p++ = way->state[i];
+    copy_char_array(&p, way->name, 30, UpperYes);
+    copy_char_array(&p, way->city, 24, UpperYes);
+    copy_char_array(&p, way->state, 2, UpperYes);
 
-    GPS_Util_Put_Short(p,way->alt);
+    GPS_Util_Put_Short(p,(US) way->alt);
     p+=sizeof(int16);
 
     for(i=0;i<2;++i) *p++ = way->cc[i];
@@ -2194,7 +2249,7 @@ static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len)
     
     p = data;
 
-    for(i=0;i<6;++i) *p++ = way->ident[i];
+    copy_char_array(&p, way->ident, 6, UpperYes);
     
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat));
     p+=sizeof(int32);
@@ -2202,15 +2257,15 @@ static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len)
     p+=sizeof(int32);
     GPS_Util_Put_Uint(p,0);
     p+=sizeof(int32);
-    for(i=0;i<40;++i) *p++ = way->cmnt[i];    
+    copy_char_array(&p, way->cmnt, 40, UpperYes);
     GPS_Util_Put_Float(p,way->dst);
     p+=sizeof(float);
 
-    for(i=0;i<30;++i) *p++ = way->name[i];
-    for(i=0;i<24;++i) *p++ = way->city[i];
-    for(i=0;i<2;++i)  *p++ = way->state[i];
+    copy_char_array(&p, way->name, 30, UpperYes);
+    copy_char_array(&p, way->city, 24, UpperYes);
+    copy_char_array(&p, way->state, 2, UpperYes);
 
-    GPS_Util_Put_Short(p,way->alt);
+    GPS_Util_Put_Short(p,(US) way->alt);
     p+=sizeof(int16);
 
     for(i=0;i<2;++i) *p++ = way->cc[i];
@@ -2349,7 +2404,10 @@ int32 GPS_A200_Get(const char *port, GPS_PWay **way)
            GPS_D108_Get(&((*way)[i]),rec->data);
            break;
        case pD109:
-           GPS_D109_Get(&((*way)[i]),rec->data);
+           GPS_D109_Get(&((*way)[i]),rec->data,109);
+           break;
+       case pD110:
+           GPS_D109_Get(&((*way)[i]),rec->data,110);
            break;
        case pD150:
            GPS_D150_Get(&((*way)[i]),rec->data);
@@ -2539,7 +2597,10 @@ int32 GPS_A201_Get(const char *port, GPS_PWay **way)
            GPS_D108_Get(&((*way)[i]),rec->data);
            break;
        case pD109:
-           GPS_D109_Get(&((*way)[i]),rec->data);
+           GPS_D109_Get(&((*way)[i]),rec->data,109);
+           break;
+       case pD110:
+           GPS_D109_Get(&((*way)[i]),rec->data,110);
            break;
        case pD150:
            GPS_D150_Get(&((*way)[i]),rec->data);
@@ -2619,7 +2680,7 @@ int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n)
     if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New()))
        return MEMORY_ERROR;
 
-    GPS_Util_Put_Short(data,n);
+    GPS_Util_Put_Short(data,(US) n);
     GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records,
                    data,2);
     if(!GPS_Write_Packet(fd,tra))
@@ -2708,7 +2769,7 @@ int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n)
        }
        
 
-       GPS_Make_Packet(&tra, method, data,len);
+       GPS_Make_Packet(&tra, method, data,(US) len);
 
        if(!GPS_Write_Packet(fd,tra))
            return gps_errno;
@@ -2768,7 +2829,7 @@ int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n)
     if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New()))
        return MEMORY_ERROR;
 
-    GPS_Util_Put_Short(data,n);
+    GPS_Util_Put_Short(data,(US) n);
     GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records,
                    data,2);
     if(!GPS_Write_Packet(fd,tra))
@@ -2850,7 +2911,10 @@ int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n)
                GPS_D108_Send(data,way[i],&len);
                break;
            case pD109:
-               GPS_D109_Send(data,way[i],&len);
+               GPS_D109_Send(data,way[i],&len, 109);
+               break;
+           case pD110:
+               GPS_D109_Send(data,way[i],&len, 110);
                break;
            case pD150:
                GPS_D150_Send(data,way[i],&len);
@@ -2874,7 +2938,7 @@ int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n)
        }
        
 
-       GPS_Make_Packet(&tra, method, data,len);
+       GPS_Make_Packet(&tra, method, data,(US) len);
 
        if(!GPS_Write_Packet(fd,tra))
            return gps_errno;
@@ -2972,7 +3036,7 @@ static void GPS_D202_Get(GPS_PWay *way, UC *s)
 
     p=s;
 
-    (*way)->rte_prot = 201;
+    (*way)->rte_prot = 202;
 #if 0
     /* D202 has only a null terminated string for rte_ident */
     (*way)->rte_num  = *p++;
@@ -3106,7 +3170,7 @@ static void GPS_D210_Send(UC *data, GPS_PWay way, int32 *len)
     
     p = data;
 
-    GPS_Util_Put_Short(p,way->rte_link_class);
+    GPS_Util_Put_Short(p,(US) way->rte_link_class);
     p+=sizeof(int16);
     for(i=0;i<18;++i) *p++ = way->rte_link_subclass[i];
 
@@ -3389,7 +3453,7 @@ int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n)
     if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New()))
        return MEMORY_ERROR;
 
-    GPS_Util_Put_Short(data,n);
+    GPS_Util_Put_Short(data,(US) n);
     GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records,
                    data,2);
     if(!GPS_Write_Packet(fd,tra))
@@ -3414,7 +3478,7 @@ int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n)
        }
 
        GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Trk_Data,
-                       data,len);
+                       data,(US) len);
 
        if(!GPS_Write_Packet(fd,tra))
            return gps_errno;
@@ -3484,7 +3548,7 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n)
     if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New()))
        return MEMORY_ERROR;
 
-    GPS_Util_Put_Short(data,n);
+    GPS_Util_Put_Short(data,(US) n);
     GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records,
                    data,2);
     if(!GPS_Write_Packet(fd,tra))
@@ -3535,7 +3599,7 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n)
        }
        
 
-       GPS_Make_Packet(&tra, method, data,len);
+       GPS_Make_Packet(&tra, method, data,(US) len);
 
        if(!GPS_Write_Packet(fd,tra))
            return gps_errno;
@@ -3765,7 +3829,6 @@ void GPS_D310_Get(GPS_PTrack *trk, UC *s)
 void GPS_D311_Get(GPS_PTrack *trk, UC *s)
 {
     UC *p;
-    UC *q;
     short identifier;
     
     p=s;
@@ -4031,7 +4094,10 @@ int32 GPS_A400_Get(const char *port, GPS_PWay **way)
            GPS_D108_Get(&((*way)[i]),rec->data);
            break;
        case pD109:
-           GPS_D109_Get(&((*way)[i]),rec->data);
+           GPS_D109_Get(&((*way)[i]),rec->data,109);
+           break;
+       case pD110:
+           GPS_D109_Get(&((*way)[i]),rec->data,110);
            break;
        case pD450:
            GPS_D450_Get(&((*way)[i]),rec->data);
@@ -4112,7 +4178,7 @@ int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n)
        return MEMORY_ERROR;
 
 
-    GPS_Util_Put_Short(data,n);
+    GPS_Util_Put_Short(data,(US) n);
     GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records,
                    data,2);
     if(!GPS_Write_Packet(fd,tra))
@@ -4176,7 +4242,7 @@ int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n)
        }
 
        GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Prx_Wpt_Data,
-                       data,len);
+                       data,(US) len);
 
        if(!GPS_Write_Packet(fd,tra))
            return gps_errno;
@@ -4417,7 +4483,7 @@ static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len)
 
     p = data;
 
-    GPS_Util_Put_Short(p,way->idx);
+    GPS_Util_Put_Short(p,(US) way->idx);
     p+=sizeof(int16);
 
     for(i=0;i<6;++i) *p++ = way->ident[i];
@@ -4429,7 +4495,7 @@ static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len)
     GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon));
     p+=sizeof(int32);
 
-    GPS_Util_Put_Short(p,way->alt);
+    GPS_Util_Put_Short(p,(US) way->alt);
     p+=sizeof(int16);
 
     for(i=0;i<24;++i) *p++ = way->city[i];
@@ -4569,7 +4635,7 @@ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n)
        return MEMORY_ERROR;
 
 
-    GPS_Util_Put_Short(data,n);
+    GPS_Util_Put_Short(data,(US) n);
     GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records,
                    data,2);
     if(!GPS_Write_Packet(fd,tra))
@@ -4621,7 +4687,7 @@ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n)
        }
 
        GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Almanac_Data,
-                       data,len);
+                       data,(US) len);
 
        if(!GPS_Write_Packet(fd,tra))
            return gps_errno;
@@ -5313,9 +5379,9 @@ void GPS_D600_Send(GPS_PPacket *packet, time_t Time)
     *p++ = ts->tm_mon+1;
     *p++ = ts->tm_mday;
 
-    GPS_Util_Put_Short(p,ts->tm_year+1900);
+    GPS_Util_Put_Short(p,(US) (ts->tm_year+1900));
     p+=2;
-    GPS_Util_Put_Short(p,ts->tm_hour);
+    GPS_Util_Put_Short(p,(US) ts->tm_hour);
     p+=2;
 
     *p++ = ts->tm_min;
index 9cfca03312f1d1b025c88d984bf6fa6f2ba99002..b3d6b3e05660818eba588b064a0d9328c8970703 100644 (file)
@@ -84,7 +84,7 @@ int32 GPS_Command_Off(const char *port)
 ** @return [int32] number of waypoint entries
 ************************************************************************/
 
-int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way, int (*cb)())
+int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way, int (*cb)(int, struct GPS_SWay **))
 {
     int32 ret=0;
 
@@ -114,7 +114,7 @@ int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way, int (*cb)())
 ** @return [int32] success
 ************************************************************************/
 
-int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)())
+int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)(struct GPS_SWay **))
 {
     int32 ret=0;
 
index 0d84157367b2605a13afbe440e5aa42db56a00d4..e8bbe1d2a8296fa0c216a3267088cc5e98e4696c 100644 (file)
@@ -28,8 +28,8 @@ int32  GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n);
 int32  GPS_Command_Get_Track(const char *port, GPS_PTrack **trk);
 int32  GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n);
 
-int32  GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way,int (*cb)());
-int32  GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)());
+int32  GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way,int (*cb)(int, struct GPS_SWay **));
+int32  GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)(struct GPS_SWay **));
 
 int32  GPS_Command_Get_Proximity(const char *port, GPS_PWay **way);
 int32  GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n);
index ad3e99b6e63a040df3308b2f98eb3e5b5234c067..89d0797c84e13fe2b79cd17655b389d7528bd0c7 100644 (file)
@@ -422,7 +422,11 @@ int32 GPS_Input_Get_Waypoint(GPS_PWay **way, FILE *inf)
            if(ret<0) return gps_errno;
            break;
        case 109:
-           ret = GPS_Input_Get_D109(&((*way)[i]),inf);
+           ret = GPS_Input_Get_D109(&((*way)[i]),inf, 109);
+           if(ret<0) return gps_errno;
+           break;
+       case 110:
+           ret = GPS_Input_Get_D109(&((*way)[i]),inf, 110);
            if(ret<0) return gps_errno;
            break;
        case 150:
@@ -550,7 +554,11 @@ int32 GPS_Input_Get_Proximity(GPS_PWay **way, FILE *inf)
            if(ret<0) return gps_errno;
            break;
        case 109:
-           ret = GPS_Input_Get_D109(&((*way)[i]),inf);
+           ret = GPS_Input_Get_D109(&((*way)[i]),inf, 109);
+           if(ret<0) return gps_errno;
+           break;
+       case 110:
+           ret = GPS_Input_Get_D109(&((*way)[i]),inf, 110);
            if(ret<0) return gps_errno;
            break;
        case 450:
@@ -1070,8 +1078,9 @@ static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf)
 ** @param [r] inf [FILE *] stream
 **
 ** @return [int32] number of entries
+** D109's and D110's are so similar, we handle both with the same function.
 ************************************************************************/
-static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf)
+static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf, int protonum)
 {
     char s[GPS_ARB_LEN];
     char *p;
index b8c5868b4270b62b594609245ea1c611e1f5d5d2..d62dd956521e22f0bcd3c8f615c71e0e37fbc397 100644 (file)
@@ -22,6 +22,7 @@
 
 
 #include <stdio.h>
+#include <ctype.h>
 #include <usb.h>
 #include "gps.h"
 #include "garminusb.h"
  * sloppy about not obeying packet boundries.  If this is too high, the
  * multiple packets responding to the device inquriy will be glommed into
  * one packet and we'll misparse them.  If it's too low, we'll get partially
- * satisfied reads.
+ * satisfied reads.  It turns out this isn't terrible becuase we still end
+ * up with DLE boundings and the upper layers (which are used to doing frame
+ * coalescion into packets anyway becuase of their serial background) will
+ * compensate.
  */
-#define TMOUT_I 0015 /*  Milliseconds to timeout intr pipe access. */
+#define TMOUT_I 0100 /*  Milliseconds to timeout intr pipe access. */
 
 int gusb_intr_in_ep;
 int gusb_bulk_out_ep;
@@ -50,7 +54,7 @@ static void garmin_usb_syncup(void);
 
 gusb_init(void)
 {
-//usb_set_debug(99);
+// usb_set_debug(99);
        usb_init();
        usb_find_busses();
        usb_find_devices();
@@ -60,7 +64,7 @@ gusb_init(void)
        return 1;
 }
 
-dump(char *msg, const unsigned char *in, int r)
+static void dump(char *msg, const unsigned char *in, int r)
 {
        int i;
        printf("%s: %d\n", msg, r);
@@ -79,49 +83,19 @@ gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz)
 {
        int r;
 
-        r = usb_bulk_write(udev, gusb_bulk_out_ep, &opkt->dbuf, sz, TMOUT_I);
-       dump ("Sent", &opkt->dbuf[0], r);
-       if (r != sz) {
-               fprintf(stderr, "Bad cmdsend\n");
+        r = usb_bulk_write(udev, gusb_bulk_out_ep, (char *)(void *)opkt->dbuf, sz, TMOUT_I);
+        if (gps_show_bytes) {
+               dump ("Sent", &opkt->dbuf[0], r);
        }
-}
-#if 0
-int
-gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz)
-{
-       int rv = 0;
-       unsigned char *obuf = &ibuf->dbuf;
-       unsigned char *buf = obuf;
-
-       while (sz) {
-               int r;
-               /*
-                * Since Garmin stupidly put bulk data on an interrupt pipe
-                * with an absurdly tiny buffer, we have to coalesce reads
-                * and we have to be fast about getting them.    (High speed
-                * polling totally misses the point of USB...)
-                */
-
-               r = usb_interrupt_read(udev, gusb_intr_in_ep, buf, sz, TMOUT_I);
-               printf("Read: %d/%d \n", r, sz);
-               if (r > 0) {
-                       buf += r;
-                       rv += r;
-                       sz -= r;
-               }
-               if (r < 0) return rv;
-               /*
-                * A zero length read AFTER a successful read means we're
-                * done.
-                */
-               if (r == 0 && rv) {
-                       break;
+       if (r != sz) {
+               fprintf(stderr, "Bad cmdsend r %d sz %d\n", r, sz);
+               if (r < 0) {
+                       fatal("usb_bulk_write failed. '%s'", 
+                               usb_strerror());
                }
        }
-       dump("completed intr Got", obuf, rv);
-       return rv;
+       return r;
 }
-#else
 
 int
 gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz)
@@ -129,7 +103,7 @@ gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz)
        unsigned char *buf = &ibuf->dbuf[0];
        unsigned char *obuf = buf;
        int r = -1, tsz = 0;
- while (r <= 0)
+
        r = usb_interrupt_read(udev, gusb_intr_in_ep, buf, sz, TMOUT_I);
 
        tsz = r;
@@ -149,27 +123,35 @@ gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz)
         }
 
        return (r);
-
-
 }
-#endif
 
 void
 garmin_usb_teardown(void)
 {
        if (udev) {
-               fprintf(stderr, "Tearing down\n");
                usb_release_interface(udev, 0);
                usb_close(udev);
                udev = NULL;
        }
 }
 
+void
 garmin_usb_start(struct usb_device *dev)
 {
-       int ret;
        int i;
-       char ibuf[4096];
+
+       if (udev) return;
+
+       /*
+        * Linux _requires_ the reset.   OSX doesn't work if we DO reset it.
+        * I really should study this more, but for now, we'll just avoid the
+        * reset on Apple's OSX.
+        */
+#if !defined (__APPLE__)
+       udev = usb_open(dev);
+       usb_reset(udev);
+       usb_close(udev);
+#endif /* APPLE */
 
        udev = usb_open(dev);
        atexit(garmin_usb_teardown);
@@ -177,15 +159,16 @@ garmin_usb_start(struct usb_device *dev)
        /*
         * Hrmph.  No iManufacturer or iProduct headers....
         */
-       if (usb_claim_interface(udev, 0) < 0) {
-               abort();
+       if (usb_set_configuration(udev, 1) < 0) {
+               fatal("usb_set_configuration failed");
        }
 
-       if (usb_set_configuration(udev, 1) < 0) {
-               abort();
+       if (usb_claim_interface(udev, 0) < 0) {
+//             abort();
        }
 
 
+
        for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) {
                struct usb_endpoint_descriptor * ep;
                ep = &dev->config->interface->altsetting->endpoint[i];
@@ -202,20 +185,19 @@ garmin_usb_start(struct usb_device *dev)
                                        gusb_intr_in_ep = EA(ep->bEndpointAddress);
                                break;
                }
-               }
-//printf("Bulk in: %d\n", gusb_bulk_in_ep);
-//printf("Bulk out: %d\n", gusb_bulk_out_ep);
-//printf("intr in: %d\n", gusb_intr_in_ep);
-
-       garmin_usb_syncup();
+       }
 
-// fprintf(stdout, "====================================================\n");
+       /*
+        *  Zero is the configuration endpoint, so if we made it through
+        * that loop without non-zero values for all three, we're hosed.
+        */
+       if (gusb_intr_in_ep && gusb_bulk_in_ep && gusb_bulk_out_ep) {
+               garmin_usb_syncup();
+       } else {
+               fatal("Could not identify endpoints on USB device.\nFound endpoints Intr In %d Bulk Out %d Bulk In %d\n", gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep);
+       }
 
        return;
-       usb_release_interface(udev, 0);
-       usb_reset(udev);
-       usb_close(udev);
-exit(1);
 }
 
 void
@@ -223,12 +205,6 @@ garmin_usb_syncup(void)
 {
        int maxct = 5;
        int maxtries;
-       char ibuf[4096];
-#if 0
-       usb_clear_halt(udev, gusb_intr_in_ep);
-       usb_clear_halt(udev, gusb_bulk_out_ep);
-       usb_clear_halt(udev, gusb_bulk_in_ep);
-#endif
 
        for (maxtries = maxct; maxtries; maxtries--) {
 
@@ -241,7 +217,9 @@ garmin_usb_syncup(void)
 
                 if ((le_read16(iresp.gusb_pkt.pkt_id) == 6) &&
                         (le_read32(iresp.gusb_pkt.datasz) == 4)) {
-                       fprintf(stderr, "Synced in %d\n", maxct - maxtries);
+                       if (gps_show_bytes) {
+                               fprintf(stderr, "Synced in %d\n", maxct - maxtries);
+                       }
 //                     fprintf(stderr, "Unit number %u\n", iresp[15] << 24 | iresp[14] << 16 | iresp[13] << 8 | iresp[12]);
                        return;
                }
@@ -253,8 +231,8 @@ return;
 static
 void garmin_usb_scan(void)
 {
+       int initted = 0;
        struct usb_bus *bus;
-       int c, i, a;
 
        for (bus = busses; bus; bus = bus->next) {
                struct usb_device *dev;
@@ -265,10 +243,15 @@ void garmin_usb_scan(void)
                         * we just take the easy way out for now.
                         */
                        if (dev->descriptor.idVendor == GARMIN_VID) {
-                               garmin_usb_start(dev);
+                               garmin_usb_start(dev);  
+                               initted++;
                        }
                }
        }
+
+       if (0 == initted) {
+               fatal("Found no Garmin USB devices.\n");
+       }
 }
 
 #endif /* !defined(NO_USB) */
index b351a0a43ccfe4e470e1d0ecd6f863dccafb8ecd..f5a893459aca7c98fd75658b36f0ac35c38d5436 100644 (file)
@@ -39,7 +39,7 @@
 GPS_PPacket GPS_Packet_New(void)
 {
     GPS_PPacket ret;
-    int hdr_size = gps_is_usb  ? sizeof(garmin_usb_packet) : sizeof(GPS_OPacket) ;
+    int hdr_size = sizeof(GPS_OPacket) ;
     if(!(ret=(GPS_PPacket )malloc(hdr_size)))
     
     {
@@ -296,7 +296,7 @@ GPS_PWay GPS_Way_New(void)
 
 void GPS_Way_Del(GPS_PWay *thys)
 {
-    free((void *)*thys);
+    xfree((void *)*thys);
 
     return;
 }
index 040efd2e76a3fe02d9d45caf1f31a64bb764e375..dd23cc4019c8987469e008fcf9c02e72e321976f 100644 (file)
@@ -2,15 +2,14 @@
  *  For portability any '32' type must be 32 bits
  *                  and '16' type must be 16 bits
  */
-typedef unsigned char UC;
-typedef short int16;
-typedef unsigned short uint16;
-typedef uint16 US;
 
-#if defined(__alpha)
-typedef int int32;
-typedef unsigned int uint32;
-#else
-typedef long int32;
-typedef unsigned long uint32;
-#endif
+/* Since GPSBabel already has an integer size abstraction layer and
+ * defs.h includes gbtypes.h before this file, just use that.
+ */
+
+typedef unsigned char UC;
+typedef gbuint16      US;
+typedef gbuint16      uint16;
+typedef gbint16       int16;
+typedef gbuint32      uint32;
+typedef gbint32       int32;
index 50606b7d2d1c032ad1ea0f0db1456436764f9b2b..8124370929b824b4e4122e311ce529223aec8e58 100644 (file)
@@ -63,7 +63,7 @@ struct LINKDATA LINK_ID[3]=
 
 struct GPS_MODEL_PROTOCOL GPS_MP[]=
 {
-    {   7,pL001,pA010,pA100,pD100,pA200,pD200,-1,-1,-1,-1,
+    {   7,pL001,pA010,pA100,pD100,pA200,pD200,-1,-1,-1,-1,-1,
           pA500,pD500
     },
     {  13,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400,
index 8c807bf16855ac738d2cb87238940c155a4e879d..6a9e75bc10a26e1f8b94a677954158a792576b7b 100644 (file)
@@ -141,6 +141,7 @@ int32 gps_pvt_transfer;
 #define pD107 107
 #define pD108 108
 #define pD109 109
+#define pD110 110
 #define pD150 150
 #define pD151 151
 #define pD152 152
@@ -246,7 +247,7 @@ int32 gps_link_type;
 
 struct GPS_MODEL_PROTOCOL
 {
-    int32 id;
+    US    id;
     int32 link;
     int32 command;
     int32 wayptt;
index d37fe6f3e4cbe5745c3f10f3a0e1d667a9e46f81..2d2f2d153fb2a77b0cb4b9862bfe03a84cc3f19f 100644 (file)
@@ -22,6 +22,7 @@
 ** Boston, MA  02111-1307, USA.
 ********************************************************************/
 #include "gps.h"
+#include "gpsusbint.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
index 138cc586604a27261f8b658bf32224574891332c..5abd56cfa1ad2b40a3b0a86234e142720692d9d9 100644 (file)
@@ -12,6 +12,7 @@ extern "C"
 
 time_t GPS_Time_Now(void);
 int32  GPS_Packet_Read(int32 fd, GPS_PPacket *packet);
+int32  GPS_Packet_Read_usb(int32 fd, GPS_PPacket *packet);
 int32  GPS_Get_Ack(int32 fd, GPS_PPacket *tra, GPS_PPacket *rec);
 int32  ajb(int32 fd);
 
index c4b299d7a9ffe448f8ac19d0130bd205663e6c29..b32ba2a27f8e12eafb277aef399a838cbe7797bc 100644 (file)
 ** Boston, MA  02111-1307, USA.
 ********************************************************************/
 #include "gps.h"
+#include "gpsusbint.h"
+
 #include <stdio.h>
 #include <errno.h>
+#include <ctype.h>
 
 
 /* @func GPS_Make_Packet ***********************************************
@@ -58,7 +61,7 @@ void GPS_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n)
     (*packet)->dle   = DLE;
     (*packet)->edle  = DLE;
     (*packet)->etx   = ETX;
-    (*packet)->n     = n;
+    (*packet)->n     = (UC) n;
     (*packet)->type  = type;
     (*packet)->bytes = 0;
 
index 60b62545f53483a63df3782fcd34c1e2a4fc5775..4883b93a36a16c0b90f405a80e13c9f8fdd43806 100644 (file)
@@ -23,6 +23,7 @@
 ** Boston, MA  02111-1307, USA.
 ********************************************************************/
 #include "gps.h"
+#include "garminusb.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -61,6 +62,11 @@ char *rxdata[] = {
  *  internal.   This means we ignore that 'fd' number that gets passed in.
  */
 
+static HANDLE comport;
+
+/*
+ * Display an error from the serial subsystem.
+ */
 void GPS_Serial_Error(char *hdr)
 {
        char msg[200];
@@ -76,8 +82,6 @@ void GPS_Serial_Error(char *hdr)
        GPS_Error(msg);
 }
 
-static HANDLE comport;
-
 int32 GPS_Serial_On(const char *port, int32 *fd)
 {
        DCB tio;
@@ -135,6 +139,7 @@ int32 GPS_Serial_On(const char *port, int32 *fd)
         * (i.e. cable unplugged, unit not turned on) values.
         */
        GetCommTimeouts (comport, &timeout);
+
        timeout.ReadIntervalTimeout = 1000; /*like vtime.  In MS. */
        timeout.ReadTotalTimeoutMultiplier = 1000;
        timeout.ReadTotalTimeoutConstant = 1000;
@@ -164,12 +169,27 @@ int32 GPS_Serial_Off(const char *port, int32 fd)
 
 int32 GPS_Serial_Chars_Ready(int32 fd)
 {
-       return 1;
+       COMSTAT lpStat;
+       DWORD lpErrors;
+
+       ClearCommError(comport, &lpErrors, &lpStat);
+       return (lpStat.cbInQue > 0);
 }
 
 int32 GPS_Serial_Wait(int32 fd)
 {
-       return 1;
+
+       if (gps_is_usb) return 1;
+
+       /* Wait a short time before testing if data is ready.
+        * The GPS II, in particular, has a noticable time responding
+        * with a response to the device inquiry and if we give up on this
+        * too soon, we fail to read the response to the A001 packet and
+        * blow our state machines when it starts streaming the capabiilties
+        * response packet.
+        */
+       Sleep(usecDELAY / 1000);
+       return GPS_Serial_Chars_Ready(fd);
 }
 
 int32 GPS_Serial_Flush(int32 fd)
@@ -180,8 +200,19 @@ int32 GPS_Serial_Flush(int32 fd)
 int32 GPS_Serial_Write(int32 ignored, const void *obuf, int size)
 {
        DWORD len;
+
+       /* 
+        * Unbelievably, the Keyspan PDA serial driver 3.2, a "Windows 
+        * Certified driver", will crash the OS on a write of zero bytes.
+        * We get such writes from upstream when there are zero payload
+        * bytes.  SO we trap those here to stop Keyspan & Windows from
+        * nuking the system.
+        */
+       if (size == 0) {
+               return 0;
+       }
        WriteFile (comport, obuf, size, &len, NULL);
-       if (len != size) {
+       if (len != (DWORD) size) {
                fatal ("Write error.   Wrote %d of %d bytes.", len, size);
        }
        return len;
@@ -221,8 +252,10 @@ static struct termios gps_ttysave;
 int32 GPS_Serial_Savetty(const char *port)
 {
     int32 fd;
+
+    if (gps_is_usb) return 1;
     
-    if((fd = open(port, O_RDWR|O_NDELAY))==-1)
+    if((fd = open(port, O_RDWR))==-1)
     {
        perror("open");
        gps_errno = SERIAL_ERROR;
@@ -238,7 +271,6 @@ int32 GPS_Serial_Savetty(const char *port)
        return 0;
     }
 
-
     if(!GPS_Serial_Close(fd,port))
     {
        gps_errno = SERIAL_ERROR;
@@ -262,8 +294,10 @@ int32 GPS_Serial_Savetty(const char *port)
 int32 GPS_Serial_Restoretty(const char *port)
 {
     int32 fd;
+
+    if (gps_is_usb) return 1;
     
-    if((fd = open(port, O_RDWR|O_NDELAY))==-1)
+    if((fd = open(port, O_RDWR))==-1)
     {
        perror("open");
        gps_errno = HARDWARE_ERROR;
@@ -312,7 +346,6 @@ int32 GPS_Serial_Open(int32 *fd, const char *port)
        return 0;
     }
 
-
     if(tcgetattr(*fd,&tty)==-1)
     {
        perror("tcgetattr");
@@ -385,6 +418,7 @@ int32 GPS_Serial_Write(int32 handle, const void *obuf, int size)
 ************************************************************************/
 int32 GPS_Serial_Flush(int32 fd)
 {
+    if (gps_is_usb) return 1;
     
     if(tcflush(fd,TCIOFLUSH))
     {
@@ -411,6 +445,8 @@ int32 GPS_Serial_Flush(int32 fd)
 
 int32 GPS_Serial_Close(int32 fd, const char *port)
 {
+    if (gps_is_usb)  return 1;
+
     if(close(fd)==-1)
     {
        perror("close");
@@ -449,7 +485,7 @@ int32 GPS_Serial_Chars_Ready(int32 fd)
     FD_SET(fd,&rec);
 
     t.tv_sec  = 0;
-    t.tv_usec = 0;
+    t.tv_usec = 1000;
     (void) select(fd+1,&rec,NULL,NULL,&t);
     if(FD_ISSET(fd,&rec))
        return 1;
index 1849cd01c812eee239512bb04553282d58e0bf0e..7d3958d4846424e4463fabeae5afcea90bcad636 100644 (file)
@@ -24,6 +24,7 @@ int32  GPS_Serial_Flush(int32 fd);
 int32  GPS_Serial_On_NMEA(const char *port, int32 *fd);
 int32  GPS_Serial_Read(int32 ignored, void *ibuf, int size);
 int32  GPS_Serial_Write(int32 ignored, const void *obuf, int size);
+void   GPS_Serial_Error(char *hdr);
 
 
 #endif
diff --git a/jeeps/gpsusbint.h b/jeeps/gpsusbint.h
new file mode 100644 (file)
index 0000000..3a0e001
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+    Definitions for internal functions of Garmin USB implementation.
+    These symbols should not be publicly used.  They're "friend" functions
+    of USB details internal to jeeps.
+
+    Copyright (C) 2005 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+int32 GPS_Packet_Read_usb(int32 fd, GPS_PPacket *packet);
+void  GPS_Make_Packet_usb(GPS_PPacket *packet, UC type, UC *data, int16 n);
+int32 GPS_Write_Packet_usb(int32 fd, GPS_PPacket packet);
+
index 6c9284decc60fa0ca0f297cfef23bc882cc1df6b..cff319a232173645a0f689f8c5776845fcc693c1 100644 (file)
     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
 
  */
-
+#include <ctype.h>
 #include "gps.h"
 #include "garminusb.h"
+#include "gpsusbint.h"
 
 int32 GPS_Packet_Read_usb(int32 fd, GPS_PPacket *packet)
 {
        int32  n;
-       UC     u;
-       UC     *p;
        int32  i;
        int32 payload_size;
        const char *m1;
@@ -56,7 +55,7 @@ int32 GPS_Packet_Read_usb(int32 fd, GPS_PPacket *packet)
         */
        (*packet)->type = le_read16(&pkt.gusb_pkt.pkt_id);
        payload_size = le_read32(&pkt.gusb_pkt.datasz);
-       (*packet)->n = payload_size;
+       (*packet)->n = (UC) payload_size;
        memcpy((*packet)->data, &pkt.gusb_pkt.databuf, payload_size);
        return payload_size;
 }
index 89fce642f2197a82c8f0bc397a00c2311b285745..8e0877a451c0cb452ea618605ba29515c28368cb 100644 (file)
 #include <stdio.h>
 #include <errno.h>
 #include "garminusb.h"
+#include "gpsusbint.h"
 
-
-void GPS_Make_Packet_usb(GPS_PPacket *packet, UC type, UC *data, int16 n)
+void 
+GPS_Make_Packet_usb(GPS_PPacket *packet, UC type, UC *data, int16 n)
 {
-    garmin_usb_packet **up = (garmin_usb_packet**) packet;
-
-    /*
-     * This is a little tacky that we're stuffing a garmin_usb_packet
-     * into a GPS_PPacket, but the packet is big enough and we have only
-     * a few places that really peek into this structure anyway...
-     */
-    memset(*up, 0, sizeof **packet);   
-    (*up)->gusb_pkt.type = 0x14; /* Garmin protocol layer */
-    le_write16((*up)->gusb_pkt.pkt_id, type);
-    le_write32((*up)->gusb_pkt.datasz, n);
-    memcpy(&(*up)->gusb_pkt.databuf, data, n);
-
-    return;
+       /*
+        * For the USB case, it's a little tacky that we just copy
+        * the params into *packet, but we really don't have any manipulations
+        * to do here.   They're done in send_packet in order to keep the
+        * contents of *packet identical for the serial and USB cases.
+        */
+
+       (*packet)->type = type;
+       memcpy((*packet)->data, data, n);
+       (*packet)->n = (UC) n;
+       
+       return;
 }
 
 int32
 GPS_Write_Packet_usb(int32 fd, GPS_PPacket packet)
 {
-       size_t ret, sz;
+       garmin_usb_packet gp = {0};
+
 
-       garmin_usb_packet *gp = (garmin_usb_packet*) packet;
-       sz = le_read32(gp->gusb_pkt.datasz);
+       /*
+        * Take the "portable" GPS_Packet data and put them into
+        * the USB packet that we will put on the wire.
+        */
+       gp.gusb_pkt.type = 0x14;
+       le_write16(&gp.gusb_pkt.pkt_id, packet->type);
+       le_write32(&gp.gusb_pkt.datasz, packet->n );
+       memcpy(&gp.gusb_pkt.databuf, packet->data, packet->n);
 
-       return  gusb_cmd_send(gp, sz + 12);
+       return  gusb_cmd_send(&gp, packet->n + 12);
 }
index 21cd9b5d9a576278ccd4ebf3056ee51f438267c9..44f15ddda1e85b6fcf4509dd9754f57fd9e3b7f8 100644 (file)
@@ -83,19 +83,20 @@ gusb_open(const char *pname)
 // }
        }
 
-       hdevinfo = SetupDiGetClassDevs( &GARMIN_GUID, NULL, NULL, 
+       hdevinfo = SetupDiGetClassDevs( (GUID *) &GARMIN_GUID, NULL, NULL, 
                        DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
 
        if (hdevinfo == INVALID_HANDLE_VALUE) {
-               fatal("XXX");
+               GPS_Serial_Error("SetupDiGetClassDevs failed");
                return 0;
        }
 
        /* Get the device associated with this index. */
        devinterface.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
-       if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, &GARMIN_GUID, 
+       if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *) &GARMIN_GUID, 
                        0, &devinterface)) {
-               fatal("blah");
+               GPS_Serial_Error("SetupDiEnumDeviceInterfaces");
+               warning("Is the unit powered up and connected?");
                return 0;
        }
 
@@ -107,7 +108,8 @@ gusb_open(const char *pname)
        devinfo.cbSize = sizeof(SP_DEVINFO_DATA);
 
        if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &devinterface, pdd, size, NULL, &devinfo)) {
-               fatal("ZZZ");
+               GPS_Serial_Error("SetupDiGetDeviceInterfaceDetail");
+               return 0;
        }
 
        /* Whew.  All that just to get something we can open... */
@@ -117,7 +119,7 @@ gusb_open(const char *pname)
                        0, NULL, OPEN_EXISTING, 0, NULL );
        if (usb_handle == INVALID_HANDLE_VALUE) {
                GPS_Serial_Error("CreateFile failed");
-               fatal("CreateFile");
+               return 0;
        }
 
        if(!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE, NULL, 0,
@@ -171,13 +173,14 @@ gusb_close(const char *portname)
                usb_handle = INVALID_HANDLE_VALUE;
 #endif
        }
+  return 0;
 }
 
 int
 gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz)
 {
        DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE;
-       unsigned char *buf = &ibuf->dbuf;
+       unsigned char *buf = (unsigned char *) &ibuf->dbuf;
        int i;
        int tsz=0;
        unsigned char *obuf = buf;
@@ -192,7 +195,7 @@ gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz)
                fatal("ioctl");
        }
                buf += rxed;
-               sz =- rxed;
+               sz  -= rxed;
                tsz += rxed;
                if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE) {
                        break;
@@ -219,7 +222,7 @@ gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz)
 {
        DWORD rsz;
        size_t i;
-       unsigned char *obuf = &opkt->dbuf;
+       unsigned char *obuf = (unsigned char *) &opkt->dbuf;
        const char *m1, *m2;
 
        /* The spec warns us about making writes an exact multiple
@@ -253,7 +256,7 @@ gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz)
 static char *
 id_unit(void)
 {
-static const char  oid[12] = {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0};
+static const unsigned char  oid[12] = {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0};
        /* 
         * Identify the unit before getting into all the protocol gunk.
         * We get two packets back, but we discard the protocol array 
diff --git a/kml.c b/kml.c
new file mode 100644 (file)
index 0000000..606e5e2
--- /dev/null
+++ b/kml.c
@@ -0,0 +1,313 @@
+/* 
+       Support for Keyhole "kml" format.
+
+       Copyright (C) 2005 Robert Lipe, robertlipe@usa.net
+       Updates by Andrew Kirmse, akirmse at google.com
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+#include "defs.h"
+#include "xmlgeneric.h"
+
+static char *deficon = NULL;
+
+static waypoint *wpt_tmp;
+
+FILE *fd;
+FILE *ofd;
+
+static
+arglist_t kml_args[] = {
+       {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING },
+       {0, 0, 0, 0, 0}
+};
+
+#define MYNAME "kml"
+
+#if NO_EXPAT
+void
+kml_rd_init(const char *fname)
+{
+       fatal(MYNAME ": This build excluded KML support because expat was not installed.\n");
+}
+
+void
+kml_read(void)
+{
+}
+#else
+
+static xg_callback     wpt_s, wpt_e;
+static xg_callback     wpt_name, wpt_desc, wpt_coord;
+
+static 
+xg_tag_mapping kml_map[] = {
+       { wpt_s,        cb_start,       "/Folder/Placemark" },
+       { wpt_e,        cb_end,         "/Folder/Placemark" },
+//     { wpt_name_s,   cb_start,       "/Folder/Placemark/name" },
+       { wpt_name,     cb_cdata,       "/Folder/Placemark/name" },
+       { wpt_desc,     cb_cdata,       "/Folder/Placemark/description" },
+//     { wpt_type,     cb_cdata,       "/Folder/Placemark/type" },
+//     { wpt_link_s,   cb_start,       "/Folder/Placemark/link" },
+//     { wpt_link,     cb_cdata,       "/Folder/Placemark/link" },
+       { wpt_coord,    cb_cdata,       "/Folder/Placemark/Point/coordinates" },
+       { NULL,         0,              NULL }
+};
+
+void wpt_s(const char *args, const char **unused) 
+{ 
+       wpt_tmp = waypt_new();
+//     wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
+}
+
+void wpt_e(const char *args, const char **unused)
+{
+       waypt_add(wpt_tmp);
+}
+
+#if 0
+void wpt_name_s(const char *args, const char **attrv)
+{
+           const char **avp = &attrv[0];
+           while (*avp) {
+                   if (0 == strcmp(avp[0], "id")) {
+                           wpt_tmp->shortname = xstrdup(avp[1]);
+                   }
+                   avp+=2;
+           }
+}
+#endif
+
+void wpt_name(const char *args, const char **unused)
+{
+       if (args) wpt_tmp->shortname = xstrdup(args);
+}
+
+void wpt_desc(const char *args, const char **unused)
+{
+       if (args) wpt_tmp->description = xstrappend(wpt_tmp->description, args);
+}
+
+void wpt_coord(const char *args, const char **attrv)
+{
+       sscanf(args, "%lf,%lf,%lf", &wpt_tmp->longitude, &wpt_tmp->latitude, &wpt_tmp->altitude);
+}
+
+static 
+void
+kml_rd_init(const char *fname)
+{
+       xml_init(fname, kml_map);
+}
+
+static
+void
+kml_read(void)
+{
+       xml_read();
+}
+#endif
+
+void
+kml_rd_deinit(void)
+{
+       xml_deinit();
+}
+
+void
+kml_wr_init(const char *fname)
+{
+       ofd = xfopen(fname, "w", MYNAME);
+}
+
+void
+kml_wr_deinit(void)
+{
+       fclose(ofd);
+}
+
+static void kml_output_timestamp(const waypoint *waypointp)
+{
+       if (waypointp->creation_time) {
+       fprintf(ofd, "\t  <TimeInstant>\n");
+       fprintf(ofd, "\t    ");
+               xml_write_time(ofd, waypointp->creation_time, "timePosition");
+       fprintf(ofd, "\t  </TimeInstant>\n");
+       }
+}
+
+/*
+ * WAYPOINTS
+ */
+
+static void kml_waypt_pr(const waypoint *waypointp)
+{
+       fprintf(ofd, "\t<Placemark>\n");
+       write_optional_xml_entity(ofd, "\t", "name", waypointp->description);
+       fprintf(ofd, "\t  <styleUrl>#waypoint</styleUrl>\n");
+
+       // Description
+       if (waypointp->url) {
+               char * odesc = xml_entitize(waypointp->url);
+               fprintf(ofd, "\t  <description>");
+               fputs("\n", ofd);
+               fputs(odesc, ofd);
+               xfree(odesc);
+               fprintf(ofd, "\n\t</description>\n");
+       }
+
+       // Location
+       fprintf(ofd, "\t  <Point>\n");
+       fprintf(ofd, "\t\t<coordinates>%f,%f,%f</coordinates>\n",
+               waypointp->longitude, waypointp->latitude, 
+               waypointp->altitude == unknown_alt ? 0.0 : waypointp->altitude);
+       fprintf(ofd, "\t  </Point>\n");
+
+       // Timestamp
+       kml_output_timestamp(waypointp);
+
+       fprintf(ofd, "\t</Placemark>\n");
+}
+
+/*
+ * TRACKPOINTS
+ */
+
+static void kml_track_hdr(const route_head *header) 
+{
+       fprintf(ofd, "<Folder>\n");
+       fprintf(ofd, "  <visibility>1</visibility>\n");
+       write_optional_xml_entity(ofd, "  ", "name", header->rte_name);
+       write_optional_xml_entity(ofd, "  ", "desc", header->rte_desc);
+}
+
+static void kml_track_disp(const waypoint *waypointp)
+{
+       fprintf(ofd, "\t<Placemark>\n");
+       fprintf(ofd, "\t  <styleUrl>#track</styleUrl>\n");
+       fprintf(ofd, "\t  <Point>\n");
+       fprintf(ofd, "\t    <coordinates>%f,%f,%f</coordinates>\n",
+               waypointp->longitude, waypointp->latitude, 
+             waypointp->altitude == unknown_alt ? 0.0 : waypointp->altitude);
+       fprintf(ofd, "\t  </Point>\n");
+
+       // Timestamp
+       kml_output_timestamp(waypointp);
+
+       fprintf(ofd, "\t</Placemark>\n");
+}
+
+static void kml_track_tlr(const route_head *header) 
+{
+       fprintf(ofd, "</Folder>\n");
+}
+
+/*
+ * ROUTES
+ */
+
+static void kml_route_hdr(const route_head *header) 
+{
+       fprintf(ofd, "<Folder>\n");
+       fprintf(ofd, "  <visibility>1</visibility>\n");
+       write_optional_xml_entity(ofd, "  ", "name", header->rte_name);
+       write_optional_xml_entity(ofd, "  ", "desc", header->rte_desc);
+}
+
+static void kml_route_disp(const waypoint *waypointp)
+{
+       fprintf(ofd, "\t<Placemark>\n");
+       fprintf(ofd, "\t  <styleUrl>#route</styleUrl>\n");
+       fprintf(ofd, "\t  <Point>\n");
+       fprintf(ofd, "\t    <coordinates>%f,%f,%f</coordinates>\n",
+               waypointp->longitude, waypointp->latitude, 
+               waypointp->altitude == unknown_alt ? 0.0 : waypointp->altitude);
+       fprintf(ofd, "\t  </Point>\n");
+       write_optional_xml_entity(ofd, "\t", "name", waypointp->description);
+
+       // Timestamp
+       kml_output_timestamp(waypointp);
+
+       fprintf(ofd, "\t</Placemark>\n");
+}
+
+static void kml_route_tlr(const route_head *header) 
+{
+       fprintf(ofd, "</Folder>\n");
+}
+
+static void kml_write_bitmap_style(const char *style, int bitmap, 
+                                      int x, int y, int width, int height)
+{
+       fprintf(ofd, "<Style id=\"%s\">\n", style);
+       fprintf(ofd, "<icon xlink:href=\"root://icons/bitmap-%d.png?x=%d&amp;y=%d&amp;w=%d&amp;h=%d\">\n",
+             bitmap, x, y, width, height);
+       fprintf(ofd, "  root://icons/bitmap-%d.png?x=%d&amp;y=%d&amp;w=%d&amp;h=%d\n",
+             bitmap, x, y, width, height);
+       fprintf(ofd, "</icon>\n");
+       fprintf(ofd, "</Style>\n");
+}  
+
+void kml_write(void)
+{
+       fprintf(ofd, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+       fprintf(ofd, "<Document xmlns:xlink=\"http://www.w3/org/1999/xlink\">\n");
+       // TODO(akirmse): Put in device name, maybe time?
+       fprintf(ofd, "<name>GPS device</name>\n");
+       fprintf(ofd, "<visibility>1</visibility>\n");
+
+       // Style settings for bitmaps
+       kml_write_bitmap_style("track", 4, 128, 0, 32, 32);
+       kml_write_bitmap_style("waypoint", 4, 160, 0, 32, 32);
+       kml_write_bitmap_style("route", 4, 160, 0, 32, 32);
+
+       fprintf(ofd, "<Folder>\n");
+       fprintf(ofd, "<name>Waypoints</name>\n");
+       fprintf(ofd, "<visibility>1</visibility>\n");
+
+       waypt_disp_all(kml_waypt_pr);
+
+       fprintf(ofd, "</Folder>\n");
+
+       // Output trackpoints
+       fprintf(ofd, "<Folder>\n");
+       fprintf(ofd, "<name>Tracks</name>\n");
+       fprintf(ofd, "<visibility>1</visibility>\n");
+       track_disp_all(kml_track_hdr, kml_track_tlr, kml_track_disp);
+       fprintf(ofd, "</Folder>\n");
+  
+       // Output routes
+       fprintf(ofd, "<Folder>\n");
+       fprintf(ofd, "<name>Routes</name>\n");
+       fprintf(ofd, "<visibility>1</visibility>\n");
+       route_disp_all(kml_route_hdr, kml_route_tlr, kml_route_disp);
+       fprintf(ofd, "</Folder>\n");
+
+       fprintf(ofd, "</Document>\n");
+}
+
+ff_vecs_t kml_vecs = {
+       ff_type_file,
+       FF_CAP_RW_WPT, /* Format can do RW_ALL */
+       kml_rd_init,    
+       kml_wr_init,    
+       kml_rd_deinit,
+       kml_wr_deinit,
+       kml_read,
+       kml_write,
+       NULL, 
+       kml_args
+};
diff --git a/lowranceusr.c b/lowranceusr.c
new file mode 100644 (file)
index 0000000..12b78e3
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+       Access to Lowrance USR files.
+       Contributed to gpsbabel by Jason Rust (jrust at rustyparts.com)
+
+       Copyright (C) 2005 Robert Lipe, robertlipe@usa.net
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+*/
+
+
+#include "defs.h"
+#include <string.h>
+#include <math.h> /* for lat/lon conversion */
+
+typedef struct lowranceusr_icon_mapping {
+       const long int  value;
+       const char              *icon;
+} lowranceusr_icon_mapping_t;
+
+/* Taken from iFinder 1.8 */
+const lowranceusr_icon_mapping_t lowranceusr_icon_value_table[] = {
+       { 10000, "diamond 1" },
+       { 10001, "diamond 2" },
+       { 10002, "diamond 3" },
+       { 10003, "x 1" },
+       { 10004, "x 2" },
+       { 10005, "x 3" },
+       { 10006, "cross" },
+       { 10007, "house" },
+       { 10008, "car" },
+       { 10009, "store" },
+       { 10010, "gas station" },
+       { 10011, "fork and spoon" },
+       { 10012, "telephone" },
+       { 10013, "airplane" },
+       { 10014, "exit sign" },
+       { 10015, "stop sign" },
+       { 10016, "exclamation" },
+       { 10017, "traffic light" },
+       { 10018, "american flag" },
+       { 10019, "person" },
+       { 10020, "restrooms" },
+       { 10021, "tree" },
+       { 10022, "mountains" },
+       { 10023, "campsite" },
+       { 10024, "picnic table" },
+       { 10025, "deer" },
+       { 10026, "deer tracks" },
+       { 10027, "turkey tracks" },
+       { 10028, "tree stand" },
+       { 10029, "bridge" },
+       { 10030, "skull and crossbones" },
+       { 10031, "fish" },
+       { 10032, "two fish" },
+       { 10033, "dive flag" },
+       { 10034, "wreck" },
+       { 10035, "anchor" },
+       { 10036, "boat" },
+       { 10037, "boat ramp" },
+       { 10038, "flag buoy" },
+       { 10039, "dam" },
+       { 10040, "swimmer" },
+       { 10041, "pier"},
+
+       { 10038, "Micro-Cache" },       /* icon for "flag buoy" */
+       { 10030, "Virtual cache" },     /* icon for "skull and crossbones" */
+       { 10032, "Multi-Cache" },       /* icon for "two fish" */
+       { 10003, "Unknown Cache" },     /* icon for "x 1" */
+       { 10018, "Locationless (Reverse) Cache" }, /* Icon for "american flag" */
+       { 10007, "Post Office" },       /* Icon for "house" */
+       { 10019, "Event Cache" },       /* Icon for "person" */
+       { 10020, "Webcam Cache" },      /* Icon for "restrooms" */
+       {        -1, NULL }
+};
+
+static FILE *file_in;
+static FILE *file_out;
+static void *mkshort_handle;
+
+static unsigned short waypt_out_count;
+
+#define MYNAME "Lowrance USR"
+
+#define MAXUSRSTRINGSIZE       256
+#define SEMIMINOR                 6356752.3142
+#define DEGREESTORADIANS       0.017453292
+#define SECSTO2000               946713599
+
+static
+size_t
+my_fwrite4(int *ptr, FILE *stream)
+{
+        int i = le_read32(ptr);
+        return fwrite(&i, 4, 1, stream);
+}
+
+static
+size_t
+my_fwrite2(short *ptr, FILE *stream)
+{
+       short i = le_read16(ptr);
+       return fwrite(&i, 2, 1, stream);
+}
+
+const char *
+lowranceusr_find_desc_from_icon_number(const int icon)
+{
+       const lowranceusr_icon_mapping_t *i;
+
+       for (i = lowranceusr_icon_value_table; i->icon; i++) {
+               if (icon == i->value) {
+                       return i->icon;
+               }
+       }
+
+       return "";
+}
+
+long int
+lowranceusr_find_icon_number_from_desc(const char *desc)
+{
+       const lowranceusr_icon_mapping_t *i;
+       long int def_icon = 10001;
+
+       if (!desc) {
+               return def_icon;
+       }
+
+       for (i = lowranceusr_icon_value_table; i->icon; i++) {
+               if (case_ignore_strcmp(desc,i->icon) == 0) {
+                       return i->value;
+               }
+       }
+
+       return def_icon;
+}
+static int
+lowranceusr_fread(void *buff, size_t size, size_t members, FILE * fp) 
+{
+       size_t br;
+
+       br = fread(buff, size, members, fp);
+
+       if (br != members) {
+               fatal(MYNAME ": requested to read %d bytes, read %d bytes.\n", members, br);
+       }
+
+       return (br);
+}
+
+static
+arglist_t lowranceusr_args[] = {
+       {0, 0, 0, 0,0 }
+};
+
+static void
+rd_init(const char *fname)
+{
+       file_in = xfopen(fname, "rb", MYNAME);
+}
+
+static void
+rd_deinit(void)
+{
+       fclose(file_in);
+}
+
+static void
+wr_init(const char *fname)
+{
+       file_out = xfopen(fname, "wb", MYNAME);
+       mkshort_handle = mkshort_new_handle();
+       waypt_out_count = 0;
+}
+
+static void
+wr_deinit(void)
+{
+       fclose(file_out);
+       mkshort_del_handle(mkshort_handle);
+}
+
+/**
+ * Latitude and longitude for USR coords are in the lowrance mercator meter
+ * format in WGS84.  The below code converts them to degrees.
+ */
+static double 
+lon_mm_to_deg(double x) {
+       return x / (DEGREESTORADIANS * SEMIMINOR);
+}
+
+static long 
+lon_deg_to_mm(double x) {
+       return (long)(x * SEMIMINOR * DEGREESTORADIANS);
+}
+
+static double 
+lat_mm_to_deg(double x) {
+       return (2 * atan(exp(x / SEMIMINOR)) - M_PI / 2) / DEGREESTORADIANS;
+}
+
+static long
+lat_deg_to_mm(double x) {
+       return (long)(SEMIMINOR * log(tan((x * DEGREESTORADIANS + M_PI / 2) / 2)));
+}
+
+static void
+data_read(void)
+{
+       char buff[MAXUSRSTRINGSIZE + 1];
+       short int NumWaypoints, MajorVersion, MinorVersion;
+       int i;
+       long int TextLen;
+
+       lowranceusr_fread(&buff[0], 2, 1, file_in);
+       MajorVersion = le_read16(&buff[0]);
+       lowranceusr_fread(&buff[0], 2, 1, file_in);
+       MinorVersion = le_read16(&buff[0]);
+       
+       if (MajorVersion < 2) {
+               fatal(MYNAME ": input file is from an old version of the USR file and is not supported\n");
+       }
+
+       lowranceusr_fread(&buff[0], 2, 1, file_in);
+       NumWaypoints = le_read16(&buff[0]);
+       for (i = 0; i < NumWaypoints; i++) {
+               waypoint *wpt_tmp;
+
+               wpt_tmp = waypt_new();
+
+               /* Object num */
+               lowranceusr_fread(&buff[0], 2, 1, file_in);
+               lowranceusr_fread(&buff[0], 4, 1, file_in);
+               wpt_tmp->latitude = lat_mm_to_deg(le_read32(&buff[0]));
+               lowranceusr_fread(&buff[0], 4, 1, file_in);
+               wpt_tmp->longitude = lon_mm_to_deg(le_read32(&buff[0]));
+               lowranceusr_fread(&buff[0], 4, 1, file_in);
+               wpt_tmp->altitude = le_read32(&buff[0]);
+
+               lowranceusr_fread(&buff[0], 4, 1, file_in);
+               TextLen = buff[0];
+               lowranceusr_fread(&buff[0], TextLen, 1, file_in);
+               buff[TextLen] = '\0';
+               wpt_tmp->shortname = xstrdup(buff);
+
+               lowranceusr_fread(&buff[0], 4, 1, file_in);
+               TextLen = buff[0];
+               if (TextLen) {
+                       lowranceusr_fread(&buff[0], TextLen, 1, file_in);
+                       buff[TextLen] = '\0';
+                       wpt_tmp->description = xstrdup(buff);
+               }
+
+               lowranceusr_fread(&buff[0], 4, 1, file_in);
+               /* Time is number of seconds since Jan. 1, 2000 */
+               wpt_tmp->creation_time = SECSTO2000 + le_read32(&buff[0]);
+
+               /* Symbol ID */
+               lowranceusr_fread(&buff[0], 4, 1, file_in);
+               wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(le_read32(&buff[0]));
+
+               /* Waypoint Type (USER, TEMPORARY, POINT_OF_INTEREST) */
+               lowranceusr_fread(&buff[0], 2, 1, file_in);
+
+               waypt_add(wpt_tmp);
+       }
+}
+
+static void
+lowranceusr_waypt_pr(const waypoint *wpt)
+{
+       int TextLen, Lat, Lon, Time, SymbolId;
+       short int WayptType;
+       char *name;
+       char *comment;
+       int alt = wpt->altitude;
+
+       /* our personal waypoint counter */
+       my_fwrite2((short *) &waypt_out_count, file_out);
+       waypt_out_count++;
+
+       Lat = lat_deg_to_mm(wpt->latitude);
+       my_fwrite4(&Lat, file_out);
+       Lon = lon_deg_to_mm(wpt->longitude);
+       my_fwrite4(&Lon, file_out);
+       my_fwrite4(&alt, file_out);
+
+       /* Try and make sure we have a name */
+       if ((! wpt->shortname) || global_opts.synthesize_shortnames) {
+               if (wpt->description && global_opts.synthesize_shortnames) {
+                       name = mkshort_from_wpt(mkshort_handle, wpt);
+               } else if (wpt->shortname) {
+                       name = xstrdup(wpt->shortname);
+               } else if (wpt->description) {
+                       name = xstrdup(wpt->description);
+               } else {
+                       name = xstrdup("");
+               }
+       } else {
+               name = xstrdup(wpt->shortname);
+       }
+
+       TextLen = strlen(name);
+       my_fwrite4(&TextLen, file_out);
+       fwrite(name, 1, TextLen, file_out);
+       xfree(name);
+
+       /**
+        * Comments aren't used by the iFinder yet so they just take up space...
+        */
+       if (0 && wpt->description && strcmp(wpt->description, wpt->shortname) != 0) {
+               comment = xstrdup(wpt->description);
+               TextLen = strlen(comment);
+               my_fwrite4(&TextLen, file_out);
+               fwrite(comment, 1, TextLen, file_out);
+               xfree(comment);
+       } else {
+               TextLen = 0;
+               my_fwrite4(&TextLen, file_out);
+       }
+
+       if (wpt->creation_time > SECSTO2000) {
+               Time = wpt->creation_time - SECSTO2000;
+       } else {
+               Time = SECSTO2000 + 1;
+       }
+       my_fwrite4(&Time, file_out);
+
+       if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) {
+               SymbolId = lowranceusr_find_icon_number_from_desc(get_cache_icon(wpt));
+       } else {
+               SymbolId = lowranceusr_find_icon_number_from_desc(wpt->icon_descr);
+       }
+
+       my_fwrite4(&SymbolId, file_out);
+
+       /* USER waypoint type */
+       WayptType = 0;
+       my_fwrite2(&WayptType, file_out);
+}
+
+static void
+data_write(void)
+{
+       short int NumWaypoints, MajorVersion, MinorVersion, NumRoutes, NumTrails, NumIcons;
+       setshort_length(mkshort_handle, 15);
+       MajorVersion = 2;
+       MinorVersion = 0;
+       NumWaypoints = waypt_count();
+
+       my_fwrite2(&MajorVersion, file_out);
+       my_fwrite2(&MinorVersion, file_out);
+       my_fwrite2(&NumWaypoints, file_out);
+       waypt_disp_all(lowranceusr_waypt_pr);
+
+       /* We don't support these yet... */
+       NumRoutes = 0;
+       my_fwrite2(&NumRoutes, file_out);
+       NumIcons = 0;
+       my_fwrite2(&NumIcons, file_out);
+       NumTrails = 0;
+       my_fwrite2(&NumTrails, file_out);
+}
+
+
+ff_vecs_t lowranceusr_vecs = {
+       ff_type_file,
+       FF_CAP_RW_WPT,
+       rd_init,
+       wr_init,
+       rd_deinit,
+       wr_deinit,
+       data_read,
+       data_write,
+       NULL, 
+       lowranceusr_args
+};
index a133febb1b3ce86aa7b09b8bf125f1505f8d42a4..8103101978a24a541015e4127e8e815394cfc531 100644 (file)
@@ -3,29 +3,19 @@
 {\colortbl;\red255\green255\blue255;}
 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
 
-\f0\b\fs24 \cf0 Acknowledgements.
-\f1\b0 \
-\
-
-\f0\b Gpsbabel
+\f0\b\fs24 \cf0 Gpsbabel
 \f1\b0  is an open-source project created and administrated by 
 \f0\b Robert Lipe
 \f1\b0 .\
 
 \f0\b MacGPSBabel
-\f1\b0  is a GUI front-end for gpsbabel. It was designed by 
+\f1\b0  is a GUI front-end for gpsbabel designed by 
 \f0\b Jeremy Atherton
 \f1\b0 .\
 \
-Thanks to the many people who have tested MacGPSBabel and given suggestions for improvement.\
-\
-
-\f0\b Legal.
-\f1\b0 \
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\
 \
-Gpsbabel and MacGPSBabel are free software; you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\
-\
-Gpsbabel and MacGPSBabel are distributed in the hope that they will be useful, but 
+This program is distributed in the hope that it will be useful, but 
 \f0\b WITHOUT ANY WARRANTY
 \f1\b0 ; without even the implied warranty of 
 \f0\b MERCHANTABILITY
@@ -41,7 +31,6 @@ You should have received a copy of the GNU General Public License along with thi
 \f0\b Robert Lipe
 \f1\b0 \
 \
-\
 For questions or comments regarding MacGPSBabel please visit http://gpsbabel.souceforge.net/ and use the gpsbabel-misc email list. Alternatively you can contact Jeremy Atherton through the address posted at the sourceforge site.\
 \
-If you would like to contribute your programming skills to either gpsbabel or MacGPSBabel please do. Join the gpsbabel-code email list and get involved.}
\ No newline at end of file
+Thanks to the many people who have tested MacGPSBabel and given suggestions for improvement. If you would like to contribute your programming skills to either gpsbabel or MacGPSBabel please do. Join the gpsbabel-code email list and get involved.}
\ No newline at end of file
index 92e08d284a77bdadf4f0ff7af0b236f7215d07e7..fb2a7b0dae32c2003f59772c8ce3bfacac539740 100644 (file)
Binary files a/macgpsbabel/English.lproj/MainMenu.nib/objects.nib and b/macgpsbabel/English.lproj/MainMenu.nib/objects.nib differ
index 1aee120ccaa4bb5e07dd3251b59dbc8b5c788e6f..76d6c12041d9b77e6df19672d3939d969668e8b3 100644 (file)
@@ -1,16 +1,33 @@
 -- MacGPSBabel: MacGPSBabel.applescript
 
 --  File created by Jeremy Atherton on Sunday, September 28, 2003.
---  Last modified by Jeremy Atherton on Tuesday, September 7, 2004.
+--  Last modified by Jeremy Atherton on Sunday, January 16, 2005.
+
+--  MacGPSBabel is part of the gpsbabel project:
+
+--             Copyright (C) 2003 - 2005 Robert Lipe
+
+--             This program is free software; you can redistribute it and/or modify
+--             it under the terms of the GNU General Public License as published by
+--             the Free Software Foundation; either version 2 of the License, or
+--             (at your option) any later version.
+
+--             This program is distributed in the hope that it will be useful,
+--             but WITHOUT ANY WARRANTY; without even the implied warranty of
+--             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--             GNU General Public License for more details.
+
+--             You should have received a copy of the GNU General Public License
+--             along with this program; if not, write to the Free Software
+--             Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
 
---  MacGPSBabel is part of the gpsbabel project and is Copyright (c) 2004 Robert Lipe.
 -- see http://gpsbabel.sourceforge.net/ for more details
 
 -- PROPERTIES AND GLOBALS --
 property fileList : {}
 property startIndex : 0
 property startState : false
-global theFiles, typeList, extList, aFile
+global theFiles, inFormatList, outFormatList, inRWList, outRWList, inTypeList, outTypeList, extList, aFile
 
 -- EVENT HANDLERS --
 
@@ -23,22 +40,19 @@ on will finish launching theObject
        make new default entry at end of default entries of user defaults with properties {name:"gpsIN", contents:startState}
        make new default entry at end of default entries of user defaults with properties {name:"gpsOUT", contents:startState}
        make new default entry at end of default entries of user defaults with properties {name:"gpsReceiver", contents:startIndex}
+       make new default entry at end of default entries of user defaults with properties {name:"filterNSSelect", contents:startIndex}
+       make new default entry at end of default entries of user defaults with properties {name:"filterEWSelect", contents:startIndex}
+       make new default entry at end of default entries of user defaults with properties {name:"filterNDeg", contents:0}
+       make new default entry at end of default entries of user defaults with properties {name:"filterNMin", contents:0.0}
+       make new default entry at end of default entries of user defaults with properties {name:"filterWDeg", contents:0}
+       make new default entry at end of default entries of user defaults with properties {name:"filterWMin", contents:0.0}
 end will finish launching
 
 on awake from nib theObject
        log "awake from nib - " & name of theObject
        if theObject is window "MacGPSBabel" then
-               -- get supported file types from gpsbabel and use these to populate the file types popup lists
-               tell window "MacGPSBabel"
-                       set popList to my getFormats()
-                       repeat with i in popList
-                               make new menu item at the end of menu items of menu of popup button "inPop" with properties {title:i, enabled:true}
-                               make new menu item at the end of menu items of menu of popup button "outPop" with properties {title:i, enabled:true}
-                       end repeat
-               end tell
-               
-               -- read current user defaults and set window controls as needed
-               my readSettings()
+               -- get supported file types from gpsbabel and use these to populate the file types popup list
+               my getFormats()
                
                -- deal with changes to MacGPSBabel window needed if any of the GPS check boxes are checked by default
                if state of button "GPSswitchIN" of window "MacGPSBabel" is equal to 1 then
@@ -53,6 +67,7 @@ end awake from nib
 -- Deal with the opening and closing of windows
 
 on will open theObject
+       
        log "will open - " & name of theObject
        -- Main Window
        if theObject is window "MacGPSBabel" then
@@ -71,6 +86,7 @@ on will open theObject
                repeat with i in popList
                        make new menu item at the end of menu items of menu of popup button "serialPop" of window "SelectGPS" with properties {title:i, enabled:true}
                end repeat
+               make new menu item at the end of menu items of menu of popup button "serialPop" of window "SelectGPS" with properties {title:"Garmin USB", enabled:true}
                
                -- read user defaults for this window
                tell user defaults
@@ -102,6 +118,8 @@ end will close
 -- handler for the File>Open menu item
 on choose menu item theObject
        log "choose menu item - " & name of theObject
+       
+       -- mainMenu File>Open
        if name of theObject is "open" then
                if visible of window "MacGPSBabel" is true then
                        if contents of text field "inputFile" of window "MacGPSBabel" is equal to "" then
@@ -128,6 +146,10 @@ on choose menu item theObject
                        my addFile()
                end if
        end if
+       
+       if name of theObject is "modePop" then
+               my getFormats()
+       end if
 end choose menu item
 
 -- HANDLERS FOR BUTTON CLICKS
@@ -245,6 +267,8 @@ on clicked theObject
                        set editable of text field "wDeg" of window "filterWindow" to true
                        set enabled of text field "wMin" of window "filterWindow" to true
                        set editable of text field "wMin" of window "filterWindow" to true
+                       set enabled of button "makeHomeButton" of window "filterWindow" to true
+                       set enabled of button "useHomeButton" of window "filterWindow" to true
                        tell window "filterWindow"
                                set first responder to text field "dist2"
                        end tell
@@ -262,6 +286,61 @@ on clicked theObject
                        set editable of text field "wDeg" of window "filterWindow" to false
                        set enabled of text field "wMin" of window "filterWindow" to false
                        set editable of text field "wMin" of window "filterWindow" to false
+                       set enabled of button "makeHomeButton" of window "filterWindow" to false
+                       set enabled of button "useHomeButton" of window "filterWindow" to false
+               end if
+       end if
+       
+       -- Filter Window - Make Home Button
+       if theObject is button "makeHomeButton" of window "filterWindow" then
+               set newNSIndex to contents of popup button "nsSelect" of window "filterWindow"
+               set newEWIndex to contents of popup button "ewSelect" of window "filterWindow"
+               set newNDeg to contents of text field "nDeg" of window "filterWindow"
+               set newNMin to contents of text field "nMin" of window "filterWindow"
+               set newWDeg to contents of text field "wDeg" of window "filterWindow"
+               set newWMin to contents of text field "wMin" of window "filterWindow"
+               tell user defaults
+                       set contents of default entry "filterNSSelect" to newNSIndex as integer
+                       set contents of default entry "filterEWSelect" to newEWIndex as integer
+                       set contents of default entry "filterNDeg" to newNDeg as integer
+                       set contents of default entry "filterNMin" to newNMin as number
+                       set contents of default entry "filterWDeg" to newWDeg as integer
+                       set contents of default entry "filterWMin" to newWMin as number
+               end tell
+       end if
+       
+       -- Filter Window - Use Home Button
+       if theObject is button "useHomeButton" of window "filterWindow" then
+               tell user defaults
+                       set homeNSSelectIndex to contents of default entry "filterNSSelect" as integer
+                       set homeEWSelectIndex to contents of default entry "filterEWSelect" as integer
+                       set homeNDeg to contents of default entry "filterNDeg" as integer
+                       set homeWDeg to contents of default entry "filterWDeg" as integer
+                       set homeNMin to contents of default entry "filterNMin" as number
+                       set homeWMin to contents of default entry "filterWMin" as number
+               end tell
+               set contents of popup button "nsSelect" of window "filterWindow" to homeNSSelectIndex
+               set contents of popup button "ewSelect" of window "filterWindow" to homeEWSelectIndex
+               set contents of text field "nDeg" of window "filterWindow" to homeNDeg
+               set contents of text field "wDeg" of window "filterWindow" to homeWDeg
+               set contents of text field "nMin" of window "filterWindow" to homeNMin
+               set contents of text field "wMin" of window "filterWindow" to homeWMin
+       end if
+       
+       -- Filter Window - Duplicate filter check boxes
+       if theObject is the button "locationFilter" of window "filterWindow" then
+               if state of button "locationFilter" of window "filterWindow" is equal to 1 then
+                       set enabled of button "allSwitch" of window "filterWindow" to 1
+               else if state of button "shortFilter" of window "filterWindow" is equal to 0 then
+                       set enabled of button "allSwitch" of window "filterWindow" to 0
+               end if
+       end if
+       
+       if theObject is the button "shortFilter" of window "filterWindow" then
+               if state of button "shortFilter" of window "filterWindow" is equal to 1 then
+                       set enabled of button "allSwitch" of window "filterWindow" to 1
+               else if state of button "locationFilter" of window "filterWindow" is equal to 0 then
+                       set enabled of button "allSwitch" of window "filterWindow" to 0
                end if
        end if
        
@@ -278,12 +357,14 @@ on clicked theObject
                        set enabled of text field "arcDist" of window "filterWindow" to true
                        set editable of text field "arcDist" of window "filterWindow" to true
                        set enabled of popup button "arcUnits" of window "filterWindow" to true
+                       set enabled of button "arcPointsSwitch" of window "filterWindow" to true
                else
                        set contents of text field "arcFile" of window "filterWindow" to ""
                        set contents of text field "arcDist" of window "filterWindow" to ""
                        set enabled of text field "arcDist" of window "filterWindow" to false
                        set editable of text field "arcDist" of window "filterWindow" to false
                        set enabled of popup button "arcUnits" of window "filterWindow" to false
+                       set enabled of button "arcPointsSwitch" of window "filterWindow" to false
                end if
        end if
        
@@ -369,8 +450,6 @@ on sendFile(fileList)
                return 0
        else if state of button "GPSswitchOUT" of window "MacGPSBabel" = 1 then
                set visible of window "SelectGPS" to true
-               set state of button "trackSwitch" of window "SelectGPS" to 0
-               set enabled of button "trackSwitch" of window "SelectGPS" to false
                return 0
        else if the title of current menu item of popup button "inPop" of window "MacGPSBabel" = "Select Input File Type" then
                display dialog "Please select an input file type" buttons {"OK"} default button 1
@@ -393,18 +472,27 @@ on convertFile(fileList)
                set filterText to ""
        end if
        
+       -- waypoint, routes or tracks
+       if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Tracks" then
+               set trackText to " -t"
+       else if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Routes" then
+               set trackText to " -r"
+       else
+               set trackText to ""
+       end if
+       
        -- create string for input files
        set fileText to ""
        repeat with theItem in fileList
                set currentInIndex to item 2 of theItem
-               set inType to item (currentInIndex) of typeList
+               set inType to item (currentInIndex) of inTypeList
                set inputFile to quoted form of item 1 of theItem
                set fileText to fileText & " -i " & inType & " -f " & inputFile
        end repeat
        
        -- create strings for output file
        set currentOutIndex to contents of popup button "outPop" of window "MacGPSBabel"
-       set outType to item (currentOutIndex) of typeList
+       set outType to item (currentOutIndex) of outTypeList
        if visible of window "filterWindow" is true then
                if state of button "smartSwitch" of window "filterWindow" is equal to 1 then
                        set smartSwitch to " -s"
@@ -443,7 +531,7 @@ on convertFile(fileList)
        end if
        -- do the script
        set thePath to POSIX path of (path to me) as string
-       set theConvertScript to (quoted form of thePath & "Contents/Resources/gpsbabel" & smartSwitch & fileText & " " & filterText & "-o " & outType & " -F " & quoted form of outputFile) as string
+       set theConvertScript to (quoted form of thePath & "Contents/Resources/gpsbabel" & smartSwitch & trackText & fileText & " " & filterText & "-o " & outType & " -F " & quoted form of outputFile) as string
        if (my runBabel(theConvertScript)) then
                display dialog "File conversion is complete" buttons {"OK"} default button 1
        else
@@ -459,7 +547,6 @@ on GPSSend()
                display dialog "Please select an output file type" buttons {"OK"} default button 1
        else
                set visible of window "SelectGPS" to true
-               set enabled of button "trackSwitch" of window "selectGPS" to true
        end if
 end GPSSend
 -- deal with uploading files to GPS receiver
@@ -471,45 +558,66 @@ on uploadFile(fileList)
                set filterText to ""
        end if
        
+       -- waypoint, routes or tracks
+       if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Tracks" then
+               set trackText to " -t"
+       else if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Routes" then
+               set trackText to " -r"
+       else
+               set trackText to ""
+       end if
+       
        -- create string for input files
        set fileText to ""
        repeat with theItem in fileList
                set currentInIndex to item 2 of theItem
-               set inType to item (currentInIndex) of typeList
+               set inType to item (currentInIndex) of inTypeList
                set inputFile to quoted form of item 1 of theItem
                set fileText to fileText & " -i " & inType & " -f " & inputFile
        end repeat
        
        -- create string for GPS unit
        if the title of popup button "gpsPop" of window "selectGPS" is equal to "Garmin" then
-               set gpsText to " garmin "
+               set gpsRText to "garmin"
        else
-               set gpsText to " magellan "
+               set gpsRText to "magellan"
        end if
        if visible of window "filterWindow" is true then
                if state of button "smartSwitch" of window "filterWindow" is equal to 1 then
                        set smartSwitch to " -s"
                        if contents of text field "smartLen" of window "filterWindow" is not equal to "" then
-                               set gpsText to gpsText & ",snlen=" & ((contents of text field "smartLen" of window "filterWindow") as integer) & " "
+                               set gpsText to gpsRText & ",snlen=" & ((contents of text field "smartLen" of window "filterWindow") as integer)
+                       else
+                               set gpsText to gpsRText
                        end if
                else
                        set smartSwitch to ""
+                       set gpsText to gpsRText
                end if
        else
                set smartSwitch to ""
+               set gpsText to gpsRText
+       end if
+       
+       -- get the port
+       if the the title of popup button "serialPop" of window "selectGPS" is equal to "Garmin USB" then
+               set serialText to "usb:"
+       else
+               set serialText to quoted form of ("/dev/cu." & (the title of popup button "serialPop" of window "selectGPS"))
        end if
        
        -- run the script
        set thePath to POSIX path of (path to me) as string
        set visible of window "SelectGPS" to false
        set visible of window "MacGPSBabel" to true
-       set serialText to "-F /dev/cu." & (the title of popup button "serialPop" of window "selectGPS")
-       set theConvertScript to (quoted form of thePath & "Contents/Resources/gpsbabel" & smartSwitch & fileText & " " & filterText & "-o " & gpsText & serialText)
+       
+       set theConvertScript to (quoted form of thePath & "Contents/Resources/gpsbabel" & smartSwitch & trackText & fileText & " " & filterText & "-o " & gpsText & " -F " & serialText)
        if (my runBabel(theConvertScript)) then
-               display dialog "Upload to" & gpsText & "GPS receiver is complete" buttons {"OK"} default button 1
+               display dialog "Upload to " & gpsRText & " GPS receiver is complete" buttons {"OK"} default button 1
        else
-               display dialog "Sorry, upload to" & gpsText & "GPS receiver failed" buttons {"OK"} default button 1
+               display dialog "Sorry, upload to " & gpsRText & " GPS receiver failed" buttons {"OK"} default button 1
        end if
+       my clearFiles()
 end uploadFile
 -- deal with downloading files from GPS receiver
 on downloadFile()
@@ -519,9 +627,14 @@ on downloadFile()
        else
                set filterText to ""
        end if
-       if state of button "trackSwitch" of window "selectGPS" is equal to 1 then
+       
+       -- waypoint, routes or tracks
+       if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Tracks" then
                set trackText to " -t"
                set outName to "Tracks."
+       else if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Routes" then
+               set trackText to " -r"
+               set outName to "Routes."
        else
                set trackText to ""
        end if
@@ -534,7 +647,7 @@ on downloadFile()
        end tell
        
        set currentOutIndex to contents of popup button "outPop" of window "MacGPSBabel"
-       set outType to item (currentOutIndex) of typeList
+       set outType to item (currentOutIndex) of outTypeList
        if visible of window "filterWindow" is true then
                if state of button "smartSwitch" of window "filterWindow" is equal to 1 then
                        set smartSwitch to " -s"
@@ -557,10 +670,15 @@ on downloadFile()
                else
                        set gpsText to " magellan "
                end if
-               set serialText to "/dev/cu." & (the title of popup button "serialPop" of window "selectGPS")
+               -- get the port
+               if the the title of popup button "serialPop" of window "selectGPS" is equal to "Garmin USB" then
+                       set serialText to "usb:"
+               else
+                       set serialText to quoted form of ("/dev/cu." & (the title of popup button "serialPop" of window "selectGPS"))
+               end if
                set visible of window "SelectGPS" to false
                set visible of window "MacGPSBabel" to true
-               set theConvertScript to (quoted form of thePath & "Contents/Resources/gpsbabel" & smartSwitch & trackText & " -i" & gpsText & "-f " & serialText & " " & filterText & " -o " & outType & " -F " & quoted form of outputFile)
+               set theConvertScript to (quoted form of thePath & "Contents/Resources/gpsbabel" & smartSwitch & trackText & " -i" & gpsText & "-f " & serialText & filterText & " -o " & outType & " -F " & quoted form of outputFile)
                if (my runBabel(theConvertScript)) then
                        display dialog "Download from" & gpsText & "GPS receiver is complete" buttons {"OK"} default button 1
                else
@@ -569,6 +687,7 @@ on downloadFile()
        else
                set outputFile to ""
        end if
+       my clearFiles()
 end downloadFile
 
 -- Send the call to gpsbabel
@@ -579,10 +698,12 @@ on runBabel(theConvertScript)
        try
                set scriptOut to do shell script theConvertScript as string
                set babelHappy to true
+               set convertYN to "ran successfully"
                log "Success! gpsbabel returned: " & scriptOut
        on error
                set scriptOut to "gpsbabel encountered an error"
                set babelHappy to false
+               set convertYN to "failed"
                log "Error! gpsbabel returned: " & scriptOut
        end try
        feedbackBusy(false)
@@ -672,7 +793,11 @@ on applyFilters()
                                set aUnit to "K"
                        end if
                        set arcDistance to (contents of text field "arcDist" of window "filterWindow") & aUnit
-                       set arcText to "-x arc,file=\"" & (contents of text field "arcFile" of window "filterWindow") & "\",distance=" & arcDistance & " "
+                       set arcText to "-x arc,file='" & (contents of text field "arcFile" of window "filterWindow") & "',distance=" & arcDistance
+                       if the state of button "arcPointsSwitch" of window "filterWindow" is equal to 1 then
+                               set arcText to arcText & ",points"
+                       end if
+                       set arcText to arcText & " "
                else
                        display dialog "Please input a distance for the arc filter" buttons ["OK"] default button 1
                        set arcText to ""
@@ -682,7 +807,7 @@ on applyFilters()
                set arcText to ""
        end if
        if state of button "polySwitch" of window "filterWindow" is equal to 1 then
-               set polyText to "-x polygon,file=\"" & (contents of text field "arcFile" of window "filterWindow") & "\" "
+               set polyText to "-x polygon,file='" & (contents of text field "polyFile" of window "filterWindow") & "'"
        else
                set polyText to ""
        end if
@@ -743,15 +868,13 @@ on clearFiles()
        
        -- reset controls to user defaults
        -- read current user defaults and set window controls as needed
-       my readSettings()
+       if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Waypoints" then
+               my readSettings()
+       end if
        
        -- deal with changes to MacGPSBabel window needed if any of the GPS check boxes are checked by default
-       if state of button "GPSswitchIN" of window "MacGPSBabel" is equal to 1 then
-               my gpsIN()
-       end if
-       if state of button "GPSswitchOUT" of window "MacGPSBabel" is equal to 1 then
-               my gpsOUT()
-       end if
+       my gpsIN()
+       my gpsOUT()
 end clearFiles
 
 
@@ -763,8 +886,6 @@ on readSettings()
                set defaultgpsIN to contents of default entry "gpsIN" as boolean
                set defaultgpsOUT to contents of default entry "gpsOUT" as boolean
        end tell
-       -- call method "setObjectValue:" of object (popup button "inPop" of window "MacGPSBabel") with parameter defaultInputIndex
-       -- call method "synchronizeTitleAndSelectedItem" of object (popup button "inPop" of window "MacGPSBabel")
        set contents of popup button "inPop" of window "MacGPSBabel" to defaultInputIndex
        set contents of popup button "outPop" of window "MacGPSBabel" to defaultOutputIndex
        set state of button "GPSswitchIN" of window "MacGPSBabel" to defaultgpsIN
@@ -816,24 +937,79 @@ on getSerial()
        return myList
 end getSerial
 
--- handler (called at startup) to check with GPS Babel which file formats it can handle. Return the result as a list
+-- handler (called at startup) to check with GPS Babel which file formats it can handle.
+-- Populates global lists with file types and capabilities
 on getFormats()
-       set myList to {}
-       set typeList to {}
+       set inFormatList to {}
+       set outFormatList to {}
+       set inTypeList to {}
+       set outTypeList to {}
        set extList to {}
        set thePath to POSIX path of (path to me) as string
-       set scriptOut to (do shell script quoted form of thePath & "Contents/Resources/gpsbabel -^1") as string
+       set scriptOut to (do shell script quoted form of thePath & "Contents/Resources/gpsbabel -^2") as string
        set theCount to count of paragraphs in scriptOut
        set defaultDelimiters to AppleScript's text item delimiters
        set AppleScript's text item delimiters to tab
        repeat with i from 1 to theCount
                set theLine to paragraph i of scriptOut
                if (first text item of theLine) is equal to "file" then
-                       set the end of typeList to the second text item of theLine
-                       set the end of extList to the third text item of theLine
-                       set the end of myList to the last text item of theLine
+                       if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Waypoints" then
+                               if the first character of the second text item of theLine is equal to "r" then
+                                       set the end of inTypeList to the third text item of theLine
+                                       set the end of inFormatList to the last text item of theLine
+                               end if
+                               if the second character of the second text item of theLine is equal to "w" then
+                                       set the end of extList to the 4th text item of theLine
+                                       set the end of outTypeList to the third text item of theLine
+                                       set the end of outFormatList to the last text item of theLine
+                               end if
+                       end if
+                       if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Tracks" then
+                               if the third character of the second text item of theLine is equal to "r" then
+                                       set the end of inTypeList to the third text item of theLine
+                                       set the end of inFormatList to the last text item of theLine
+                               end if
+                               if the 4th character of the second text item of theLine is equal to "w" then
+                                       set the end of extList to the 4th text item of theLine
+                                       set the end of outTypeList to the third text item of theLine
+                                       set the end of outFormatList to the last text item of theLine
+                               end if
+                       end if
+                       if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Routes" then
+                               if the 5th character of the second text item of theLine is equal to "r" then
+                                       set the end of inTypeList to the third text item of theLine
+                                       set the end of inFormatList to the last text item of theLine
+                               end if
+                               if the 6th character of the second text item of theLine is equal to "w" then
+                                       set the end of extList to the 4th text item of theLine
+                                       set the end of outTypeList to the third text item of theLine
+                                       set the end of outFormatList to the last text item of theLine
+                               end if
+                       end if
                end if
        end repeat
        set AppleScript's text item delimiters to defaultDelimiters
-       return myList
+       
+       -- set current menu item of popup button "inPop" of window "MacGPSBabel" to menu item 1 of menu of popup button "inPop" of window "MacGPSBabel"
+       -- set current menu item of popup button "outPop" of window "MacGPSBabel" to menu item 1 of menu of popup button "outPop" of window "MacGPSBabel"
+       
+       tell window "MacGPSBabel"
+               if (count of menu items of popup button "inPop") is greater than 0 then
+                       delete every menu item of menu of popup button "inPop"
+                       make new menu item at the end of menu items of menu of popup button "inPop" with properties {title:"Select Input File Type", enabled:true}
+                       delete every menu item of menu of popup button "outPop"
+                       make new menu item at the end of menu items of menu of popup button "outPop" with properties {title:"Select Output File Type", enabled:true}
+               end if
+               repeat with i in inFormatList
+                       make new menu item at the end of menu items of menu of popup button "inPop" with properties {title:i, enabled:true}
+               end repeat
+               repeat with i in outFormatList
+                       make new menu item at the end of menu items of menu of popup button "outPop" with properties {title:i, enabled:true}
+               end repeat
+       end tell
+       
+       if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Waypoints" then
+               my readSettings()
+       end if
+       
 end getFormats
\ No newline at end of file
index c2d2aad14f2513f8f93a04dc9345aed5c528c48b..2d326e9a54beb26ea6ad76fd6d825982ab855bc3 100644 (file)
                29B97319FDCFA39411CA2CEA = {
                        isa = PBXFileReference;
                        lastKnownFileType = wrapper.nib;
-                       path = MainMenu.nib;
+                       path = English.lproj/MainMenu.nib;
                        refType = 4;
                        sourceTree = "<group>";
                };
                F514A08D05A6164F01A80064 = {
                        isa = PBXFileReference;
                        lastKnownFileType = "compiled.mach-o.executable";
-                       path = gpsbabel;
+                       path = ../gpsbabel;
                        refType = 4;
                        sourceTree = "<group>";
                };
index f7a023b16707f63804b75c118259d22e5487bb82..062742634b3be3930da305496510145aed44d221 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+    Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -47,5 +47,8 @@ typedef struct icon_mapping {
 const char * mag_find_descr_from_token(const char *token);
 const char * mag_find_token_from_descr(const char *icon);
 
+unsigned int mag_checksum(const char *const buf);
+char * m330_cleanse(char *istring);
+
 waypoint * mag_trkparse(char *trkmsg);
 void mag_rteparse(char *rtemsg);
diff --git a/maggeo.c b/maggeo.c
new file mode 100644 (file)
index 0000000..3bf237c
--- /dev/null
+++ b/maggeo.c
@@ -0,0 +1,239 @@
+/*
+    Magellan ".gs" files as they appear on USB of Explorist 400,500,600.
+
+    Copyright (C) 2005, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <ctype.h>
+#include "defs.h"
+#include "xmlgeneric.h"
+#include "magellan.h"
+
+#define MYNAME "maggeo"
+
+static FILE *maggeofile_in;
+static FILE *maggeofile_out;
+static void *desc_handle = NULL;
+
+static void
+maggeo_writemsg(const char * const buf)
+{
+       unsigned int osum = mag_checksum(buf);
+       fprintf(maggeofile_out, "$%s*%02X\r\n",buf, osum);
+}
+
+static void
+maggeo_rd_init(const char *fname)
+{
+       maggeofile_in = xfopen(fname, "rb", MYNAME);
+}
+
+static void
+maggeo_rd_deinit(void)
+{
+        fclose(maggeofile_in);
+}
+
+static void
+maggeo_wr_init(const char *fname)
+{
+       maggeofile_out = xfopen(fname, "wb", MYNAME);
+       desc_handle = mkshort_new_handle();
+       setshort_length(desc_handle, 20);
+       setshort_badchars(desc_handle, "\"$,");
+}
+
+static void
+maggeo_wr_deinit(void)
+{
+       maggeo_writemsg("PMGNCMD,END");
+       fclose(maggeofile_out);
+}
+
+static void
+maggeo_read(void)
+{
+       fatal("Not implemented yet.");
+}
+
+/*
+ * Note: returns allocated buffer that must be freed by caller.
+ */
+static 
+char *
+maggeo_fmtdate(time_t t)
+{
+       #define SZ 16
+
+       char *cbuf = xmalloc(SZ);
+       struct tm *tm = NULL;
+       int date;
+       tm = gmtime(&t);
+
+       if ( t && tm ) {
+               date = tm->tm_mday * 100000 + (1+tm->tm_mon) * 1000 + 
+                          tm->tm_year;
+               snprintf(cbuf, SZ, "%07d", date);
+       } else {
+               cbuf[0] = '\0';
+       }
+       return cbuf;
+}
+
+/*
+ * Append an optional UTF string to buf, prepending a comma, 
+ * cleansing it of NMEA-isms and decomposing to ASCII as we go.
+ */
+static
+append(char *buf, const char *str)
+{
+       char *cleansed1, *cleansed2;
+
+       strcat(buf, ",");
+
+       if (!str) {
+               return;
+       }
+
+       cleansed1 = str_utf8_to_ascii(str);
+       cleansed2 = m330_cleanse(cleansed1);
+
+       strcat(buf, cleansed2);
+
+       xfree(cleansed1);
+       xfree(cleansed2);
+
+}
+
+static void
+maggeo_waypt_pr(const waypoint *waypointp)
+{
+       char obuf[4096];
+       char dtbuf[10];
+       double ilon, ilat;
+       double lon, lat;
+       int lon_deg, lat_deg;
+       char *shortname;
+       char *cname = NULL;
+       char *ctype = NULL;
+       char *placer = NULL;
+       char *lfounddate = NULL;
+       char *placeddate = NULL;
+
+       ilat = waypointp->latitude;
+       ilon = waypointp->longitude;
+       shortname = waypointp->shortname;
+
+       lon = fabs(ilon);
+       lat = fabs(ilat);
+
+       lon_deg = lon;
+       lat_deg = lat;
+
+       lon = (lon - lon_deg) * 60.0;
+       lat = (lat - lat_deg) * 60.0;
+
+       lon = (lon_deg * 100.0 + lon);
+       lat = (lat_deg * 100.0 + lat);
+
+       ctype = gs_get_cachetype(waypointp->gc_data.type);
+       placeddate = maggeo_fmtdate(waypointp->creation_time);
+       lfounddate = maggeo_fmtdate(waypointp->gc_data.last_found);
+       cname = mkshort(desc_handle, waypointp->notes ? waypointp->notes : waypointp->shortname);
+       placer = waypointp->gc_data.placer;
+
+       /*
+        * As of this writing on 05/04, the firmware in the units will
+        * let you write fields of just about any width, but appears to
+        * only use the following:
+        * shortname - 8 chars
+        * cname - 20 chars (scrolls in some places, not others)
+        * placer - display limited by width
+        * hint - 50 chars
+        * cache type - appears to be parsed by f/w for icon matching.
+        * 
+        * 
+        */
+       snprintf(obuf, sizeof(obuf),
+               "PMGNGEO,%4.3f,%c,%08.3f,%c,%04.0f,F",
+                lat, ilat < 0 ? 'S' : 'N',
+                lon, ilon < 0 ? 'W' : 'E',
+                waypointp->altitude == unknown_alt ?
+                        0 : waypointp->altitude);
+       append(obuf, shortname);
+       append(obuf, cname);
+       append(obuf, placer);
+       append(obuf, waypointp->gc_data.hint);
+       append(obuf, ctype);
+       append(obuf, placeddate);
+       append(obuf, lfounddate);
+
+       if (waypointp->gc_data.diff/10.0)
+               sprintf(obuf + strlen(obuf), ",%3.1f", 
+                       waypointp->gc_data.diff/10.0);
+       else
+               strcat(obuf, ",");
+
+       if (waypointp->gc_data.terr/10.0)
+               sprintf(obuf + strlen(obuf), ",%3.1f", 
+                       waypointp->gc_data.terr/10.0);
+       else
+               strcat(obuf, ",");
+
+       if (lfounddate) xfree(lfounddate);
+       if (placeddate) xfree(placeddate);
+
+       maggeo_writemsg(obuf);
+
+}
+
+static void
+maggeo_write(void)
+{
+       waypt_disp_all(maggeo_waypt_pr);
+}
+
+static
+char *
+strconsume(char *instr, int *eaten)
+{
+       const char *origstr = instr;
+       char *s = instr;
+       char *e = instr;
+       int ct;
+
+       while (e && *e && *e != ',')
+               *e++;
+
+       *eaten = e - s;
+       
+       return (xstrndup(instr, e-s));
+       
+}
+
+
+ff_vecs_t maggeo_vecs = {
+       ff_type_file,
+       FF_CAP_RW_WPT,
+       maggeo_rd_init,
+       maggeo_wr_init,
+       maggeo_rd_deinit,
+       maggeo_wr_deinit,
+       maggeo_read,
+       maggeo_write,
+};
index 392974e40e22797d582a2434a3f9c6dd5e948ca8..8e9370dc96c7844f6518e8fe3edd17bba3f506b1 100644 (file)
--- a/magnav.c
+++ b/magnav.c
@@ -106,7 +106,7 @@ data_read(void)
                struct tm tm;
 
                memset (&tm, sizeof(tm), 0);
-               wpt_tmp = xcalloc(sizeof(*wpt_tmp),1);
+               wpt_tmp = waypt_new();
                rec = (struct record *) pdb_rec->data;
                wpt_tmp->altitude = be_read32(&rec->elevation); 
 
@@ -145,7 +145,7 @@ my_writewpt(const waypoint *wpt)
        char *vdata;
        time_t tm_t;
        const char *sn = global_opts.synthesize_shortnames ?
-               mkshort(mkshort_handle, wpt->description) :
+               mkshort_from_wpt(mkshort_handle, wpt) :
                wpt->shortname;
 
        rec = xcalloc(sizeof(*rec)+56,1);
@@ -179,7 +179,7 @@ my_writewpt(const waypoint *wpt)
        
        be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0));
        be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0));
-       be_write32(&rec->elevation, wpt->altitude);
+       be_write32(&rec->elevation, (unsigned int) (wpt->altitude));
 
        rec->plot = 0;
        rec->unknown3 = 'a';
@@ -205,7 +205,7 @@ my_writewpt(const waypoint *wpt)
        vdata[1] = '\0';
        vdata += 2;
        
-       opdb_rec = new_Record (0, 0, ct++, vdata-(char *)rec, (const ubyte *)rec);
+       opdb_rec = new_Record (0, 0, ct++, (uword) (vdata-(char *)rec), (const ubyte *)rec);
 
        if (opdb_rec == NULL) {
                fatal(MYNAME ": libpdb couldn't create record\n");
@@ -263,6 +263,7 @@ data_write(void)
 
 ff_vecs_t magnav_vec = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
index 87424e2049d2bb05e7277c539d5b51c6a66bacd9..48151b532ad93dc0d0ee7ea8da610c69a876f04e 100644 (file)
@@ -1,7 +1,7 @@
 /*
     Communicate Thales/Magellan serial protocol.
 
-    Copyright (C) 2002, 2003, 2004 Robert Lipe, robertlipe@usa.net
+    Copyright (C) 2002, 2003, 2004, 2005 Robert Lipe, robertlipe@usa.net
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #include "magellan.h"
 
 int bitrate = 4800;
+int wptcmtcnt;
+int wptcmtcnt_max;
 #define MYNAME "MAGPROTO"
+#define MAXCMTCT 200
 
 #define debug_serial  (global_opts.debug_level > 1)
 
@@ -38,10 +41,12 @@ static void mag_handoff(void);
 static void *mkshort_handle = NULL;
 static char *deficon = NULL;
 static char *bs = NULL;
+static char *cmts = NULL;
 static char *noack = NULL;
 static char *nukewpt = NULL;
 static int route_out_count;
 static int waypoint_read_count;
+static int wpt_len = 8;
 
 typedef enum {
        mrs_handoff = 0,
@@ -171,7 +176,9 @@ pid_to_model_t pid_to_model[] =
        { mm_meridian, 35, "ProMark 2" },
        { mm_sportrak, 36, "SporTrak Map/Pro" },
        { mm_sportrak, 37, "SporTrak" },
+       { mm_meridian, 38, "FX324 Plotter" },
        { mm_meridian, 39, "Meridian Color" },
+       { mm_meridian, 40, "FX324C Plotter" },
        { mm_sportrak, 41, "Sportrak Color" },
        { mm_sportrak, 42, "Sportrak Marine" },
        { mm_meridian, 43, "Meridian Marine" },
@@ -207,7 +214,7 @@ m315_cleanse(char *istring)
 /*
  * Do same for 330, Meridian, and SportTrak.
  */
-static char *
+char *
 m330_cleanse(char *istring)
 {
        static char m330_valid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
@@ -229,7 +236,7 @@ m330_cleanse(char *istring)
  * Given a protocol message, compute the checksum as needed by 
  * the Magellan protocol.
  */
-static unsigned int 
+unsigned int 
 mag_checksum(const char * const buf)
 {
        int csum = 0;
@@ -359,7 +366,7 @@ mag_verparse(char *ibuf)
                case mm_meridian:
                case mm_sportrak:
                        icon_mapping = map330_icon_table;
-                       setshort_length(mkshort_handle, 8);
+                       setshort_length(mkshort_handle, wpt_len);
                        setshort_mustupper(mkshort_handle, 0);
                        mag_cleanse = m330_cleanse;
                        break;
@@ -611,7 +618,7 @@ termwrite(char *obuf, int size)
                return;
        }
        WriteFile (comport, obuf, size, &len, NULL);
-       if (len != size) {
+       if ((int) len != size) {
                fatal(MYNAME ":.  Wrote %d of %d bytes.\n", len, size);
        }
 }
@@ -711,6 +718,8 @@ static
 arglist_t mag_sargs[] = {
        {"baud", &bs, "Numeric value of bitrate (baud=4800)", NULL,
                ARGTYPE_INT },
+       {"maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", 
+               NULL, ARGTYPE_INT },
        {"noack", &noack, "Suppress use of handshaking in name of speed",
                NULL, ARGTYPE_BOOL},
        {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING },
@@ -786,8 +795,18 @@ mag_rd_init(const char *portname)
 }
 
 static void
-mag_wr_init(const char *portname)
+mag_wr_init_common(const char *portname)
 {
+       if (bs) {
+               bitrate=atoi(bs);
+       }
+
+       if (cmts) {
+               wptcmtcnt_max = atoi(cmts);
+       } else {
+               wptcmtcnt_max = MAXCMTCT ;
+       }
+
 #if __WIN32__
        if (!terminit(portname, 1)) {
                is_file = 1;
@@ -823,6 +842,24 @@ mag_wr_init(const char *portname)
        QUEUE_INIT(&rte_wpt_tmp);
 }
 
+/*
+ * Entry point for extended (explorist) points.
+ */
+static void
+magX_wr_init(const char *portname)
+{
+       wpt_len = 20;
+       mag_wr_init_common(portname);
+       setshort_length(mkshort_handle, wpt_len);
+}
+
+static void
+mag_wr_init(const char *portname)
+{
+       wpt_len = 8;
+       mag_wr_init_common(portname);
+}
+
 static void
 mag_deinit(void)
 {
@@ -1150,7 +1187,7 @@ mag_waypt_pr(const waypoint *waypointp)
        const char *icon_token=NULL;
        char *owpt;
        char *odesc;
-       char *isrc;
+       char *isrc = NULL;
 
        ilat = waypointp->latitude;
        ilon = waypointp->longitude;
@@ -1179,11 +1216,12 @@ mag_waypt_pr(const waypoint *waypointp)
 
        isrc = waypointp->notes ? waypointp->notes : waypointp->description;
        owpt = global_opts.synthesize_shortnames ?
-                        mkshort(mkshort_handle, isrc) : waypointp->shortname;
+                        mkshort_from_wpt(mkshort_handle, waypointp) : waypointp->shortname;
        odesc = isrc ? isrc : "";
        owpt = mag_cleanse(owpt);
 
-       if (waypointp->gc_data.diff && waypointp->gc_data.terr) {
+       if (!global_opts.no_smart_icons &&
+           waypointp->gc_data.diff && waypointp->gc_data.terr) {
                sprintf(ofmtdesc, "%d/%d %s", waypointp->gc_data.diff, 
                        waypointp->gc_data.terr, odesc);
                odesc = mag_cleanse(ofmtdesc);
@@ -1191,11 +1229,20 @@ mag_waypt_pr(const waypoint *waypointp)
                odesc = mag_cleanse(odesc);
        }
 
-       sprintf(obuf, "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.lf,M,%-.8s,%-.30s,%s",
+       /*
+        * For the benefit of DirectRoute (which uses waypoint comments
+        * to deliver turn-by-turn popups for street routing) allow a 
+        * cap on the comments delivered so we leave space for it to route.
+        */
+       if (odesc && /* !is_file && */ (wptcmtcnt++ >= wptcmtcnt_max))
+               odesc[0] = 0;
+
+       sprintf(obuf, "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.lf,M,%-.*s,%-.46s,%s",
                lat, ilat < 0 ? 'S' : 'N',
                lon, ilon < 0 ? 'W' : 'E',
                waypointp->altitude == unknown_alt ?
                        0 : waypointp->altitude,
+               wpt_len,
                owpt,
                odesc,
                icon_token);
@@ -1332,7 +1379,8 @@ mag_route_trl(const route_head * rte)
                        thisline++;
 
                        sprintf(obuff, "PMGNRTE,%d,%d,c,%d,%s,%s", 
-                               numlines, thisline, route_out_count,
+                               numlines, thisline, 
+                               rte->rte_num ? rte->rte_num : route_out_count,
                                buff1, buff2);
 
                        mag_writemsg(obuff);
@@ -1363,7 +1411,11 @@ mag_write(void)
         * Whitespace is actually legal, but since waypoint name length is
         * only 8 bytes, we'll conserve them.
         */
+
        setshort_whitespace_ok(mkshort_handle, 0);
+
+       wptcmtcnt = 0;
+
        switch (global_opts.objective)
        {
                case trkdata:
@@ -1386,6 +1438,7 @@ mag_write(void)
  */
 ff_vecs_t mag_svecs = {
        ff_type_serial,
+       FF_CAP_RW_ALL,
        mag_rd_init,    
        mag_wr_init,    
        mag_deinit,     
@@ -1398,6 +1451,7 @@ ff_vecs_t mag_svecs = {
 
 ff_vecs_t mag_fvecs = {
        ff_type_file,
+       FF_CAP_RW_ALL,
        mag_rd_init,    
        mag_wr_init,    
        mag_deinit,     
@@ -1407,3 +1461,18 @@ ff_vecs_t mag_fvecs = {
        NULL, 
        mag_fargs
 };
+
+/*
+ * Extended (Explorist) entry tables.
+ */
+ff_vecs_t magX_fvecs = {
+       ff_type_file,
+       FF_CAP_RW_ALL,
+       mag_rd_init,    
+       magX_wr_init,   
+       mag_deinit,     
+       mag_deinit,     
+       mag_read,
+       mag_write,
+       NULL, 
+};
diff --git a/main.c b/main.c
index 78acd8dfeb4c766b38ce52ff216d4946adfc8ea5..2b1afdfe411f0c0a2e90bdcc3d095051d67ac1cb 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+    Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -38,6 +38,7 @@ usage(const char *pname, int shorter)
 "    The input type and filename are specified with the -i INTYPE\n"
 "    and -f INFILE options. The output type and filename are specified\n"
 "    with the -o OUTTYPE and -F OUTFILE options.\n"
+"    If '-' is used for INFILE or OUTFILE, stdin or stdout will be used.\n"
 "\n"
 "    In the second form of the command, INFILE and OUTFILE are the\n"
 "    first and second positional (non-option) arguments.\n"
@@ -202,7 +203,19 @@ main(int argc, char *argv[])
                                global_opts.masked_objective |= RTEDATAMASK;
                                break;
                        case 'N':
-                               global_opts.no_smart_icons = 1;
+                               switch(argv[argn][2]) {
+                                       case 'i':
+                                               global_opts.no_smart_icons = 1;
+                                               break;
+                                       case 'n':
+                                               global_opts.no_smart_names = 1;
+                                               break;
+                                       default:
+                                               global_opts.no_smart_names = 1;
+                                               global_opts.no_smart_icons = 1;
+                                               break;
+                               }
+                               
                                break;
                        case 'x':
                                optarg = argv[argn][2]
@@ -236,6 +249,7 @@ main(int argc, char *argv[])
                        case 'v':
                                switch(argv[argn][2]) {
                                case 's': global_opts.verbose_status = 1; break;
+                               case 'S': global_opts.verbose_status = 2; break;
                                }
                                break;
 
diff --git a/make-an1sym.pl b/make-an1sym.pl
new file mode 100644 (file)
index 0000000..5af6814
--- /dev/null
@@ -0,0 +1,361 @@
+#!/usr/bin/perl\r
+\r
+=pod\r
+\r
+    This script reads the DeLorme Stock Symbols .dim file and writes code\r
+    to be included in the .an1 format handler.\r
+\r
+    You MUST have a copy of the DeLorme .dim file; you can download it\r
+    from the support section of DeLorme's Web site.  You want the one\r
+    that contains all of the symbols.\r
+\r
+    To use this script:\r
+\r
+      perl make-an1sym.pl <DeLormeStockSymbols.dim >an1sym.h\r
+\r
+    Copyright (C) 2005 Ronald L. Parker (babelan1perl@parkrrrr.com) \r
+                   and Robert Lipe\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+\r
+=cut\r
+\r
+# read a data structure from the input file.  \r
+sub shiftunpack {\r
+   my $pattern = shift;\r
+   my @result = unpack( $pattern, $file );\r
+   my $str = pack( $pattern, @result );\r
+   $file = substr( $file, length( $str ));\r
+   @result;\r
+}\r
+\r
+sub skip_bytes {\r
+   my $count = shift;\r
+   $file = substr( $file, $count );\r
+}\r
+\r
+sub decodeGuid {\r
+   @guid = unpack( 'LSSSCCCCCC', shift );\r
+   my $sub = undef;\r
+   my $guid2 = sprintf( '{0x%8.8x,{0x%4.4x, 0x%4.4x, 0x%4.4x},'.\r
+            ' {0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x}}',\r
+            @guid );\r
+   $sub = $substitutions{ sprintf('%8.8x', @guid)};\r
+   ($guid2, $sub);\r
+}\r
+\r
+sub DoImage {\r
+    # image information - the 'type' we read was actually the low word of the hotspot X coord.\r
+    ($hotspotxhi, $hotspoty, $unk1, $guid, $name ) = \r
+          shiftunpack( 'slla[16]C/a*' );\r
+    $hotspotx = $rec_type + 0x10000*$hotspotxhi;\r
+\r
+    ($guid2,$sub) = decodeGuid( $guid );\r
+    $name = $sub if ( $sub );\r
+    print qq(  {$guid2,\n            "$name"},\n);\r
+}\r
+\r
+%substitutions = (\r
+    # everything up to and including "mud" is defined\r
+    "012dfac2", "Tractor",\r
+    "012dfac3", "Combine Harvester",\r
+    "012dfac7", "Front-End Loader",\r
+    "fd163780", "Power Shovel",\r
+    "fd163781", "Road Grader",\r
+    "fd163784", "Road Roller",\r
+    "fd163787", "Dump Truck",\r
+    "5673d712", "Skid-Steer Loader",   # Bobcat is a registered trademark\r
+    "b86045ac", "Highway Sign",\r
+    "1e129e95", "Orange Cone",\r
+    "adee7d54", "Barricade",\r
+    "a170000f", "Flagger",\r
+    "a425f90e", "Construction Sign",\r
+    "0805b240", "Construction Flasher",\r
+    "56721a6c", "Transit",\r
+    # this group of 8 arrows is defined\r
+    "83f91421", "Small Arrow Left",\r
+    "83f91422", "Small Arrow Right",\r
+    "83f91423", "Small Arrow Up",\r
+    "83f91424", "Small Arrow Down",\r
+    "83f91425", "Small Arrow Up Left",\r
+    "83f91426", "Small Arrow Up Right",\r
+    "83f91427", "Small Arrow Down Left",\r
+    "83f91428", "Small Arrow Down Right",\r
+    "83f91429", "Large Arrow Left",\r
+    "83f9142a", "Large Arrow Right",\r
+    "83f9142b", "Large Arrow Up",\r
+    "83f9142c", "Large Arrow Down",\r
+    "83f9142d", "Large Arrow Down Right",\r
+    "83f9142e", "Large Arrow Down Left",\r
+    "83f9142f", "Large Arrow Up Left",\r
+    "83f91430", "Large Arrow Up Right",\r
+    "8ff0aad1", "Accommodation",\r
+    "af7bf199", "Australia",\r
+    "6bbcc9d1", "Blue Dome Cross",\r
+    "fff920fe", "Green Dome Cross", \r
+    "57e75924", "Business",\r
+    "b09ef4a7", "Airplane",\r
+    "f2833c22", "Amusement Recreation", # tent? on a green background\r
+    "6f0317d6", "Green Square", \r
+    "18a6d3c0", "Red Triangle", \r
+    "86e68ea7", "Red Triangle and Green Square",\r
+    "6afd74bf", "City 4",\r
+    "49dfeb74", "White Square",\r
+    "3eed62c6", "White Triangle",\r
+    "6b521940", "Red Black Diamond Flag",\r
+    "bb8ebaa3", "Yellow Diamond Flag",\r
+    "8e118862", "Small Pink Square",\r
+    "d0ef64c2", "Store",\r
+    "a22b08fb", "Camping",\r
+    "27f57c69", "Green Diamond Flag",\r
+    "e07abb38", "Red Diamond Flag",\r
+    "3a124ac9", "Red Green Diamond Flag",\r
+    "64ed669b", "White Globe",\r
+    "3cb10adc", "Yellow Globe",\r
+    "2779347d", "", #???\r
+    "3ad63f7b", "Black Cross",\r
+    "3e89481e", "Church",\r
+    "68622c10", "Small Dark Green Square",\r
+    "42c6a873", "Small Black Square",\r
+    "50e3b06e", "Danger",\r
+    "369d0b22", "Construction Business",\r
+    "10603b6c", "Airport",\r
+    "8328aab7", "City 5",\r
+    "96411287", "USA",\r
+    "b2f98627", "Diver Down",\r
+    "3fce26d0", "Light Yellow Square",\r
+    "b4b68597", "Education Technology", \r
+    "35d2e6a8", "Computer",\r
+    "4ddc4e96", "Amusement Recreation Red", \r
+    "79f58929", "Telephone Red",\r
+    "0083b377", "Exit",\r
+    "0c232891", "Exit with Services",\r
+    "af63e7c2", "Pizza",\r
+    "d419c693", "Financial Services",\r
+    "70740a81", "City 3",\r
+    "9a582ff6", "Food Store",\r
+    "3cd31689", "", #???\r
+    "952557a6", "", #??? white/black circle\r
+    "03dc278c", "Driving Range",\r
+    "acd28bab", "Golf Municipal",\r
+    "984e7139", "Golf Private",\r
+    "ec5828ab", "Golf Public",\r
+    "b0120d99", "Golf Resort",\r
+    "2ce7685a", "Golf Semi Private",\r
+    "10397049", "Medical Service",\r
+    "2fc28df6", "Home Furnishings",\r
+    "910313db", "Industrial",\r
+    "9e442c6e", "", #???\r
+    "37e2fe4a", "", #???\r
+    "3c756e09", "", #???\r
+    "a1245b1c", "Manufacturing",\r
+    "5bddbd7a", "Note",\r
+    "cb6777e1", "City",\r
+    "bc168c08", "Air Base",\r
+    "a8857b0f", "Battlefield",\r
+    "06db55c1", "Mining",\r
+    "cc61b277", "Mountain",\r
+    "fde13186", "Capital",\r
+    "b14d90d1", "Route",\r
+    "7eabc63f", "Overnight",\r
+    "ac39d8b9", "Route End Active",\r
+    "e1b9d86b", "Route End Inactive",\r
+    "98712315", "Fuel Stop",\r
+    "e5ea5b38", "Route Start Active",\r
+    "18fd0d49", "Route Start Inactive",\r
+    "2f52144b", "Route Stop Active",\r
+    "faf8d826", "Route Stop Inactive",\r
+    "ff44cae2", "Route Via",\r
+    "5a50d59b", "Radiation Green",\r
+    "19556023", "Radiation Red",\r
+    "a54be251", "Electricity",\r
+    "d793ff0c", "Personal Furnishings",\r
+    "00f90733", "Personal Services",\r
+    "ea677f24", "Telephone Black",\r
+    "2d8a05b5", "Government Light",\r
+    "40c64dfc", "Airport Red Square",\r
+    "f27adb5d", "Propeller Aircraft",\r
+    "5a718e13", "Jet Aircraft",\r
+    "0a471039", "Government",\r
+    "4a59da2f", "USA Regional",\r
+    "f16500a9", "House 2",\r
+    "7b05524d", "Picnic",\r
+    "b88ad7a1", "Restaurant",\r
+    "dc48a20a", "Store 2",\r
+    "6b5ab040", "", # ???\r
+    "153b2cff", "Blue Star",\r
+    "f276f6b3", "", # ???\r
+    "91d242c8", "Running",\r
+    "8b0078db", "Transportation",\r
+    "0599f6c9", "Fishing",\r
+    "7389128c", "Automotive",\r
+    "0362b593", "Cloudy",\r
+    "f0717a94", "Partly Cloudy",\r
+    "14486bbc", "Mostly Cloudy",\r
+    "7a258c70", "Tornado",\r
+    "eff260d4", "Lightning",\r
+    "c3d70220", "Rain",\r
+    # everything else is defined\r
+    # They defined two red flags.  Ooops.\r
+    "f2dfbc95", "Red Flag 2"\r
+);\r
+\r
+sub print_header {\r
+print <<'END';\r
+/* \r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+                       THIS FILE IS AUTOMATICALLY GENERATED\r
+\r
+\r
+                       Please change make-an1sym.pl and\r
+                       regenerate it rather than changing\r
+                       this file directly.\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+*/\r
+\r
+/*\r
+    Read DeLorme drawing files (.an1) - supplemental (included by an1.c)\r
\r
+    Copyright (C) 2005 Ron Parker and Robert Lipe.\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+\r
+ */\r
+\r
+struct defguid {\r
+       GUID guid;\r
+       char *name;\r
+} default_guids[] = {\r
+END\r
+}\r
+\r
+sub print_footer {\r
+print <<'END';\r
+};\r
+\r
+int FindIconByName( const char *name, GUID *guid ) {\r
+       int i = 0; \r
+       for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ )\r
+       {\r
+               if ( !case_ignore_strcmp(name, default_guids[i].name)) {\r
+                       memcpy( guid, &(default_guids[i].guid), sizeof(GUID));\r
+                       return 1;\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+\r
+int FindIconByGuid( GUID *guid, char **name ) {\r
+       int i = 0; \r
+       for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ )\r
+       {\r
+               if ( !memcmp(guid, &default_guids[i].guid, sizeof(GUID))) {\r
+                       *name = default_guids[i].name;\r
+                       return 1;\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+END\r
+}\r
+\r
+\r
+# read file\r
+undef $/;\r
+$file = <>;\r
+\r
+# read file header\r
+($magic, $unk1 ) = shiftunpack( 'ss' );\r
+\r
+# read bitmap info\r
+($unk2) = shiftunpack( 'l' );\r
+\r
+print_header;\r
+\r
+while ( length($file) ) {\r
+  ($rec_type) = shiftunpack( 's' );\r
+  if ( $rec_type == 0x4c49 ) { # 'IL'\r
+    # I don't know what this structure is, but it appears twice in my test files.\r
+    ($unk10101, $unke, $unkc, $unk18_1, $unk18_2, $unkneg1_1,\r
+     $unk20, $unkneg1_2, $unkneg1_3) = shiftunpack( 'lsssslsll');\r
+  }\r
+  elsif ( $rec_type == 0x4d42 ) { # 'BM'\r
+    # This is a standard BMP file, documented in MSDN.\r
+    # BITMAPFILEHEADER\r
+    ($fhsize, $res_0_1, $res_0_2, $bitoffset) = shiftunpack( 'lssl' );\r
+    # BITMAPINFOHEADER\r
+    ($bmisize, $width, $height, $planes, $bpp, $compression, \r
+     $size, $xppm, $yppm, $colused, $colimprt ) = shiftunpack( 'lllssllllll');\r
+    # palette\r
+    $palettesize = $bitoffset - $bmisize - 14; # 14 bytes in BMFH, including the 'BM'\r
+    skip_bytes( $palettesize );\r
+    # image\r
+    skip_bytes( $size );\r
+  }\r
+  elsif ($rec_type == 0 ) { # crap\r
+    ($a, $b, $c, $d, $e, $f) = shiftunpack( 'llllll' );\r
+    if ( $c ) { \r
+      $file = pack( 'llllll', ($a, $b, $c, $d, $e, $f)) . $file;\r
+      DoImage;\r
+    }\r
+  }\r
+  else {\r
+    DoImage;\r
+  }\r
+} \r
+\r
+print_footer;\r
index fecb23f871c1a8ce0a8e2d8ec264fb12d09bf690..55e73bd7670771bf0678e7f9b5ad8ace45d0928b 100644 (file)
@@ -149,7 +149,7 @@ decode(char *buf)
 //     for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) {
        for(pdb_rec=pdb_rec->next; pdb_rec; pdb_rec=pdb_rec->next) {
                waypoint *wpt_tmp;
-               char *vdata;
+               char *vdata = 0;
                char *edata;
                struct tm tm = {0};
 
@@ -157,7 +157,7 @@ decode(char *buf)
                edata = (char *) rec + pdb_rec->data_len;
 
                for (; vdata < edata; rec = (struct record *) vdata) {
-                       wpt_tmp = xcalloc(sizeof(*wpt_tmp),1);
+                       wpt_tmp = waypt_new();
                        wpt_tmp->latitude = Lat1 + 
                                be_read16(&rec->lat1d) / LATDIV2; 
                        wpt_tmp->longitude = Lon1 + 
@@ -266,8 +266,6 @@ my_writewpt(const waypoint *wpt)
 static void
 data_write(void)
 {
-       queue *elem, *tmp;
-
        static char *appinfo = 
                "\0\x01"
                "User\0\0\0\0\0\0\0\0\0\0\0\0"
@@ -311,6 +309,7 @@ data_write(void)
 
 ff_vecs_t mapopolis_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
index 7477a043f68b290f416f45f495e4fbf54e19f6ea..fa538c342138e009b75701b5ac554ef8ebdd59f5 100644 (file)
--- a/mapsend.c
+++ b/mapsend.c
@@ -125,7 +125,7 @@ mapsend_wpt_read(void)
        my_fread4(&wpt_count, mapsend_file_in);
        
        while (wpt_count--) {
-               wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
+               wpt_tmp = waypt_new();
 
                if (fread(&scount, sizeof(scount), 1, mapsend_file_in) < 1) {
                        fatal(MYNAME ": out of data reading %d waypoints\n",
@@ -183,7 +183,7 @@ mapsend_wpt_read(void)
                my_fread4(&wpt_count, mapsend_file_in);
                
                while (wpt_count--) {
-                       wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
+                       wpt_tmp = waypt_new();
 
                        /* waypoint name */
                        fread(&scount, sizeof(scount), 1, mapsend_file_in);
@@ -259,7 +259,7 @@ mapsend_track_read(void)
                        centisecs = 0;
                }
 
-               wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
+               wpt_tmp = waypt_new();
                wpt_tmp->latitude = -wpt_lat;
                wpt_tmp->longitude = wpt_long;
                wpt_tmp->creation_time = time;
@@ -316,21 +316,43 @@ mapsend_waypt_pr(const waypoint *waypointp)
        static int cnt = 0;
        const char *iconp = NULL;
        const char *sn = global_opts.synthesize_shortnames ? 
-               mkshort(mkshort_handle, waypointp->description) :
+               mkshort_from_wpt(mkshort_handle, waypointp) :
                waypointp->shortname;
+       char *tmp;
 
-       c = sn ? strlen(sn) : 0;
+       /*
+        * The format spec doesn't call out the character set of waypoint
+        * name and description.  Empirically, we can see that it's 8859-1,
+        * but if we create mapsend files containing those, Mapsend becomes
+        * grumpy uploading the resulting waypoints and being unable to deal
+        * with the resulting comm errors.
+        * 
+        * Ironically, our own Magellan serial module strips the "naughty"
+        * characters, keeping it more in definition with their own serial
+        * spec. :-)
+        * 
+        * So we just decompose the utf8 strings to ascii before stuffing
+        * them into the Mapsend file.
+        */
+
+       tmp = str_utf8_to_ascii(sn);
+       c = tmp ? strlen(tmp) : 0;
        fwrite(&c, 1, 1, mapsend_file_out);
-       fwrite(sn, c, 1, mapsend_file_out);
+       fwrite(tmp, c, 1, mapsend_file_out);
+       if (tmp)
+               xfree(tmp);
 
-       if (waypointp->description) 
-               c = strlen(waypointp->description);
+       tmp = str_utf8_to_ascii(waypointp->description);
+       if (tmp)
+               c = strlen(tmp);
        else
                c = 0;
 
        if (c > 30) c = 30;
        fwrite(&c, 1, 1, mapsend_file_out);
-       fwrite(waypointp->description, c, 1, mapsend_file_out);
+       fwrite(tmp, c, 1, mapsend_file_out);
+       if (tmp)
+               xfree(tmp);
 
        /* #, icon, status */
        n = ++cnt;
@@ -522,7 +544,7 @@ void mapsend_track_disp(const waypoint * wpt)
        my_fwrite8(&dbl, mapsend_file_out);
 
        /* altitude */
-       i = wpt->altitude;
+       i = (int) wpt->altitude;
        my_fwrite4(&i, mapsend_file_out);
        
        /* time */
@@ -584,6 +606,7 @@ mapsend_wpt_write(void)
 
 ff_vecs_t mapsend_vecs = {
        ff_type_file,
+       FF_CAP_RW_ALL,
        mapsend_rd_init,
        mapsend_wr_init,
        mapsend_rd_deinit,
index d303814ac5d417e72d4a02880291148e7f5a935f..948d760849240d3fcf3a2f04d7e9f4f6956783bb 100644 (file)
@@ -95,6 +95,7 @@ arglist_t mps_args[] = {
  * A wrapper to ensure the doubles we fwrite are in correct endianness.
  */
 
+void
 le_fwrite64(void *ptr, int sz, int ct, FILE *stream)
 {
        unsigned char cbuf[8];
@@ -107,6 +108,7 @@ le_fwrite64(void *ptr, int sz, int ct, FILE *stream)
        fwrite(cbuf, 8, 1, stream);
 }
 
+void
 le_fread64(void *ptr, int sz, int ct, FILE *stream)
 {
        unsigned char cbuf[8];
@@ -411,7 +413,7 @@ mps_fileHeader_r(FILE *mps_file, int *mps_ver)
 static void
 mps_fileHeader_w(FILE *mps_file, int mps_ver)
 {
-       char hdr[100];
+       unsigned char hdr[100];
        int reclen;
 
        strcpy (hdr, "MsRc");
@@ -467,10 +469,10 @@ mps_fileHeader_w(FILE *mps_file, int mps_ver)
 static void
 mps_mapsegment_r(FILE *mps_file, int mps_ver)
 {
-       char hdr[100];
        int reclen;
 
        /* At the moment we're not doing anything with map segments, but here's the template code as if we were
+       char hdr[100];
        fread(&CDid, 4, 1, mps_file);
        reclen = le_read32(&CDid);
 
@@ -499,10 +501,10 @@ mps_mapsegment_r(FILE *mps_file, int mps_ver)
 static void
 mps_mapsetname_r(FILE *mps_file, int mps_ver)
 {
-       char hdr[100];
        int reclen;
 
        /* At the moment we're not doing anything with mapsetnames, but here's the template code as if we were
+       char hdr[100];
        mps_readstr(mps_file, hdr, sizeof(hdr));
        char mapsetnamename[very large number?];
        strcpy(mapsetnamename,hdr);
@@ -857,7 +859,7 @@ mps_route_wpt_w_unique_wrapper(const waypoint *wpt)
                }
        }
 }
-
+#if 0
 /*
  * wrapper to include the mps_ver_out information
  * This one always writes a waypoint. If it has been written before
@@ -869,7 +871,6 @@ mps_waypoint_w_uniqloc_wrapper(waypoint *wpt)
 {
        waypoint *wptfound = NULL;
        char                    *newName;
-       unsigned int    uniqueNum = 0;
 
        /* Search for this waypoint in the ones already written */
        wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname);
@@ -901,6 +902,7 @@ mps_waypoint_w_uniqloc_wrapper(waypoint *wpt)
                mps_wpt_q_add(&written_wpt_head, wpt);
        }
 }
+#endif
 
 /*
  * read in from file a route record
@@ -918,9 +920,7 @@ mps_route_r(FILE *mps_file, int mps_ver, route_head **rte)
        int     interlinkStepCount;
        int     thisInterlinkStep;
        unsigned int    mpsclass;
-       int     FFsRead;
 
-       time_t  dateTime = 0;
        route_head *rte_head;
        int rte_count;
 
@@ -1177,7 +1177,6 @@ mps_routehdr_w(FILE *mps_file, int mps_ver, const route_head *rte)
 {
        unsigned int reclen;
        unsigned int rte_datapoints;
-       unsigned int colour = 0;                /* unknown colour */
        int                     rname_len;
        char            *rname;
        char            hdr[20];
@@ -1317,7 +1316,6 @@ mps_routehdr_w(FILE *mps_file, int mps_ver, const route_head *rte)
                        fwrite(zbuf, 9, 1, mps_file);
                }
                else {
-                       unsigned char cbuf[8];
                        hdr[0] = 1;
 
                        fwrite(hdr, 1 , 1, mps_file);
@@ -1346,7 +1344,6 @@ mps_routedatapoint_w(FILE *mps_file, int mps_ver, const waypoint *rtewpt)
        unsigned char hdr[10];
        int                     lat;
        int                     lon;
-       time_t          t = rtewpt->creation_time;
        char            zbuf[20];
        char            ffbuf[20];
        char            *src;
@@ -1912,6 +1909,8 @@ mps_write(void)
        int                             reclen;
        int                             reclen2;
        unsigned int    tocopy;
+       unsigned int    block;
+       
        long                    tempFilePos;
        unsigned int    mpsWptClass;
 
@@ -1988,9 +1987,10 @@ mps_write(void)
                                fseek(mps_file_temp, tempFilePos, SEEK_SET);
 
                                /* copy the data using a "reasonably" sized buffer */
-                               for(tocopy = reclen2; tocopy > 0; tocopy -= sizeof(copybuf)) {
-                                       fread(copybuf, (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy), 1, mps_file_temp);
-                                       fwrite(copybuf, (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy), 1, mps_file_out);
+                               for(tocopy = reclen2; tocopy > 0; tocopy -= block) {
+                                 block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy);
+                                 fread(copybuf, block, 1, mps_file_temp);
+                                 fwrite(copybuf, block, 1, mps_file_out);
                                }
                        }
                        else break;
@@ -2026,6 +2026,7 @@ mps_write(void)
        /* prior to writing any tracks as requested, if we're doing a merge, read in the rtes
           from the original file and then write them out, ready for tracks to follow
        */
+
        /* if ((mpsmergeout) && (global_opts.objective != rtedata)) { */
        if ((mpsmergeout) && (! doing_rtes)) {
                while (!feof(mps_file_temp)) {
@@ -2035,9 +2036,11 @@ mps_write(void)
                                fwrite(&reclen, 4, 1, mps_file_out);    /* write out untouched */
                                fwrite(&recType, 1, 1, mps_file_out);
 
-                               for(tocopy = reclen2; tocopy > 0; tocopy -= sizeof(copybuf)) {
-                                       fread(copybuf, (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy), 1, mps_file_temp);
-                                       fwrite(copybuf, (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy), 1, mps_file_out);
+                               /* copy the data using a "reasonably" sized buffer */
+                               for(tocopy = reclen2; tocopy > 0; tocopy -= block) {
+                                 block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy);
+                                 fread(copybuf, block, 1, mps_file_temp);
+                                 fwrite(copybuf, block, 1, mps_file_out);
                                }
                        }
                        else break;
@@ -2095,9 +2098,11 @@ mps_write(void)
                                fwrite(&reclen, 4, 1, mps_file_out);    /* write out untouched */
                                fwrite(&recType, 1, 1, mps_file_out);
 
-                               for(tocopy = reclen2; tocopy > 0; tocopy -= sizeof(copybuf)) {
-                                       fread(copybuf, (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy), 1, mps_file_temp);
-                                       fwrite(copybuf, (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy), 1, mps_file_out);
+                               /* copy the data using a "reasonably" sized buffer */
+                               for(tocopy = reclen2; tocopy > 0; tocopy -= block) {
+                                 block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy);
+                                 fread(copybuf, block, 1, mps_file_temp);
+                                 fwrite(copybuf, block, 1, mps_file_out);
                                }
                        }
                        else break;
@@ -2140,10 +2145,13 @@ mps_write(void)
                        fwrite(&reclen, 4, 1, mps_file_out);    /* write out untouched */
                        fwrite(&recType, 1, 1, mps_file_out);
 
-                       for(tocopy = reclen2; tocopy > 0; tocopy -= sizeof(copybuf)) {
-                               fread(copybuf, (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy), 1, mps_file_temp);
-                               fwrite(copybuf, (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy), 1, mps_file_out);
+                       /* copy the data using a "reasonably" sized buffer */
+                       for(tocopy = reclen2; tocopy > 0; tocopy -= block) {
+                         block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy);
+                         fread(copybuf, block, 1, mps_file_temp);
+                         fwrite(copybuf, block, 1, mps_file_out);
                        }
+                       
                        if (recType != 'V') {
                                fread(&reclen, 4, 1, mps_file_temp);
                                reclen2 = le_read32(&reclen);
@@ -2163,6 +2171,7 @@ mps_write(void)
 
 ff_vecs_t mps_vecs = {
        ff_type_file,
+       FF_CAP_RW_ALL,
        mps_rd_init,
        mps_wr_init,
        mps_rd_deinit,
index f5833cb7d0ce72d0a5c97ae5b3442023dc33f0e8..0bbea79a288e2e84868c0bfd26492d91e10b5f49 100644 (file)
@@ -1,7 +1,7 @@
 CC=/usr/local/cross-tools/bin/i386-mingw32msvc-gcc
 VPATH=..:../shapelib
 
-FILES=gpsbabel.exe libexpat.dll ../win32/gpsbabelfront.exe ../README* ../COPYING
+FILES=gpsbabel.exe libexpat.dll ../win32/GPSBabelGUI.exe ../README* ../COPYING
 
 gpsbabel.exe:  wintesto.cmd
 
@@ -24,3 +24,17 @@ mkwintesto: mkwintesto.c
 
 wintesto.cmd: mkwintesto
        ./mkwintesto ../testo
+
+# The "usbfree" target is useful for generating an executable that 
+# works on NT 3.5 or 4.0 since it doesn't have USB support and tanks
+# on our libsetupapi references.
+
+usbfree:
+       $(MAKE) INHIBIT_USB=-DNO_USB gpsbabel-usbfree.exe
+
+gpsbabel-usbfree.exe: $(OBJS)
+       $(CC) -static $(CFLAGS) $(OBJS) lib/libexpat.a -o gpsbabel-usbfree.exe
+       zip -j /tmp/gpsbabel-nousb-$(VERSIOND).zip gpsbabel-usbfree.exe
+
+
+
index e58576b30f2e3445835980f72ee06fc5e969a9f2..0df95a78d686adbbd9aec48997c4c86f17ef9098 100644 (file)
@@ -126,6 +126,27 @@ DEL %TMPDIR%\tiger
 @echo.\r
 CALL :COMPARE %TMPDIR%\tiger %TMPDIR%\tiger2\r
 \r
+REM \r
+REM Lowrance USR.  Binary, and also slightly lossy because of the math to\r
+REM convert lat/long.  It also doesn't support description, which makes it\r
+REM awkward  to test.\r
+REM \r
+DEL %TMPDIR%\lowrance1.usr\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i geo -f geocaching.loc -o lowranceusr -F %TMPDIR%\lowrance1.usr\r
+@echo off\r
+@echo.\r
+CALL :BINCOMPARE %TMPDIR%\lowrance1.usr reference\lowrance.usr\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i lowranceusr -f %TMPDIR%\lowrance1.usr -o lowranceusr -F %TMPDIR%\lowrance1.usr\r
+@echo off\r
+@echo.\r
+REM And because of the FP rounding, we can't even read our file, write it back\r
+REM and get the same data.  Sigh. \r
+REM bincompare reference/lowrance.usr  ${TMPDIR}/lowrance1.usr\r
+\r
 REM CSV (Comma separated value) data.\r
 \r
 @echo on\r
@@ -250,7 +271,7 @@ REM identical reference.
 %PNAME% -i holux -f reference\paris.wpo -o holux -F %TMPDIR%\paris.wpo\r
 @echo off\r
 @echo.\r
-CALL :COMPARE reference\paris.wpo %TMPDIR%\paris.wpo\r
+REM compare reference/paris.wpo ${TMPDIR}/paris.wpo\r
 \r
 REM Magellan NAV Companion for PalmOS\r
 REM This format is hard to test, because each record and the database itself\r
@@ -582,6 +603,34 @@ REM Navicache.
 CALL :COMPARE %TMPDIR%\navi.wpt reference\navicache.ref\r
 REM \r
 \r
+REM \r
+REM CoastalExplorer..\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -r -i coastexp -f reference\coastexp.nob -o gpx -F %TMPDIR%\coastexp.gpx\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\coastexp.gpx reference\coastexp.ref\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -r -i gpx -f %TMPDIR%\coastexp.gpx -o coastexp -F %TMPDIR%\coastexp.nob\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\coastexp.nob reference\coastexp.ref2\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -w -i coastexp -f reference\coastexp.nob -o gpx -F %TMPDIR%\coastexp.gpx\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\coastexp.gpx reference\coastexp.ref3\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -w -i gpx -f %TMPDIR%\coastexp.gpx -o coastexp -F %TMPDIR%\coastexp.nob\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\coastexp.nob reference\coastexp.ref4\r
+REM \r
+\r
 REM PsiTrex.  A text format that can't be handled by XCSV due to context of\r
 REM data based on other data values in the file\r
 REM Waypoints first\r
@@ -809,6 +858,87 @@ CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc2_igc.out
 @echo.\r
 CALL :COMPARE %TMPDIR%\igc.gpx reference\igc2_gpx.out\r
 \r
+REM \r
+REM Google Maps XML test\r
+REM \r
+DEL %TMPDIR%\google.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i google -f reference\google.xml -o arc -F %TMPDIR%\google.out\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\google.out reference\google.arc\r
+\r
+DEL %TMPDIR%\google.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i google -f reference\google.js -o arc -F %TMPDIR%\google.out\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\google.out reference\google.arc\r
+\r
+REM \r
+REM DeLorme .an1 tests\r
+REM \r
+DEL %TMPDIR%\an1.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i an1 -f reference\foo.an1 -o csv -F %TMPDIR%\an1.out\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\an1.out reference\an1-in.ref\r
+\r
+DEL %TMPDIR%\an1.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i an1 -f reference\foo.an1 -o an1 -F %TMPDIR%\an1.out\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\an1.out reference\an1-an1.ref\r
+\r
+DEL %TMPDIR%\an1.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i xmap -f reference\xmap -o an1 -F %TMPDIR%\an1.out \r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\an1.out reference\an1-out.ref\r
+\r
+DEL %TMPDIR%\an1.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i google -f reference\google.js -o an1 -F %TMPDIR%\an1.out\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\an1.out reference\an1-line-out.ref\r
+\r
+REM \r
+REM TomTom .ov2 tests\r
+REM \r
+\r
+DEL %TMPDIR%\ov2.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i arc -f reference\google.arc -o tomtom -F %TMPDIR%\ov2.out\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\ov2.out reference\ov2-arc-out.ref\r
+\r
+DEL %TMPDIR%\ov2.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i geo -f reference\gl.loc -o tomtom -F %TMPDIR%\ov2.out\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\ov2.out reference\ov2-geo-out.ref\r
+\r
+DEL %TMPDIR%\ov2.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i tomtom -f reference\ov2-geo-out.ref -o gpsutil -F %TMPDIR%\ov2.out\r
+@echo off\r
+@echo.\r
+CALL :COMPARE %TMPDIR%\ov2.out reference\ov2-in.ref\r
 \r
 REM \r
 REM XCSV "human readable" tests\r
@@ -873,3 +1003,36 @@ REM
 @echo off\r
 @echo.\r
 \r
+REM \r
+REM 'tabsep' isn't really tested in any non-trivial way, but we do exercise\r
+REM it.\r
+REM \r
+\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i geo -f geocaching.loc  -o tabsep -F - | ${PNAME} -i tabsep -f - -o geo -F %TMPDIR%\tabsep.out\r
+%PNAME% -i geo -f geocaching.loc  -o geo -F %TMPDIR%\geotabsep.out\r
+@echo off\r
+@echo.\r
+\r
+REM \r
+REM Now do the same for custom - it has the same issues.\r
+REM \r
+\r
+CALL :COMPARE %TMPDIR%\tabsep.out %TMPDIR%\geotabsep.out\r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i geo -f geocaching.loc  -o custom -F - | ${PNAME} -i custom -f - -o geo -F %TMPDIR%\custom.out\r
+%PNAME% -i geo -f geocaching.loc  -o geo -F %TMPDIR%\geocustom.out\r
+@echo off\r
+@echo.\r
+\r
+REM \r
+REM Write something to the various output-only formats\r
+REM \r
+@echo on\r
+@echo Testing...\r
+%PNAME% -i geo -f geocaching.loc -o text -F %TMPDIR%\text.out -o html -F %TMPDIR%\html.out -o vcard -F %TMPDIR%\vcard.out #-o palmdoc -F %TMPDIR%\pd.out\r
+@echo off\r
+@echo.\r
+\r
index 15d69bceaff009c878efc7a3c0a22921a396803f..ce45907b8617e6de366e9375e9649b11f28fcb7c 100644 (file)
--- a/mkshort.c
+++ b/mkshort.c
@@ -43,6 +43,7 @@ typedef struct {
        int whitespaceok;
        unsigned int target_len;
        char *badchars;
+       char *goodchars;
        int must_uniq;
        queue namelist[PRIME];
        int depth[PRIME];
@@ -149,18 +150,25 @@ mkshort_del_handle(void *h)
        mkshort_handle *hdr = h;
        int i;
 
-       if (hdr) {
-               for (i = 0; i < PRIME; i++) {
-                       queue *e, *t;
-                       QUEUE_FOR_EACH(&hdr->namelist[i], e, t) {
-                               uniq_shortname *s = (uniq_shortname *) e;
-                               dequeue(e);
-                               xfree(s->orig_shortname);
-                               xfree(s);
+       if (!hdr)
+               return;
+
+       for (i = 0; i < PRIME; i++) {
+               queue *e, *t;
+               QUEUE_FOR_EACH(&hdr->namelist[i], e, t) {
+                       uniq_shortname *s = (uniq_shortname *) e;
+#if 0
+                       if (global_opts.verbose_status >= 2 && s->conflictctr) {
+                               fprintf(stderr, "%d Output name conflicts: '%s'\n",  
+                                       s->conflictctr, s->orig_shortname);
                        }
+#endif
+                       dequeue(e);
+                       xfree(s->orig_shortname);
+                       xfree(s);
                }
-               xfree(hdr);
        }
+       xfree(hdr);
 }
 
 /*
@@ -179,8 +187,10 @@ delete_last_vowel(int start, char *istring, int *replaced)
        *replaced = 0;
        for (l = strlen(istring); l > start; l--) {
                if (strchr(vowels, istring[l-1])) {
-                       char *ostring = xstrdup(istring);
-
+                       char *ostring;
+                       /* If vowel is the first letter of a word, keep it.*/
+                       if (istring[l-2] == ' ') continue;
+                       ostring = xstrdup(istring);
                        strncpy(&ostring[l-1], &istring[l], 1+strlen(istring)-l);
                        ostring[strlen(istring)-1] = 0;
                        *replaced = 1;
@@ -230,6 +240,13 @@ setshort_badchars(void *h, const char *s)
                hdl->badchars = xstrdup(s);
        }
 }
+void
+setshort_goodchars(void *h, const char *s)
+{
+       mkshort_handle *hdl = h;
+
+       hdl->goodchars = xstrdup(s);
+}
 
 void
 setshort_mustupper(void *h, int i)
@@ -245,7 +262,6 @@ setshort_mustuniq(void *h, int i)
        hdl->must_uniq = i;
 }
 
-
 char *
 #ifdef DEBUG_MEM
 MKSHORT(void *h, const char *istring, DEBUG_PARAMS )
@@ -272,21 +288,14 @@ mkshort(void *h, const char *istring)
                ostring = nstring;
        }
 
-       /*
-        * Look at the back of the string for " by BLAH" and whack 
-        * it there.
-        */
-       nstring = xxstrdup(ostring, file, line);
-       l = strlen (nstring);
-       while (l > 0) {
-               if (strncmp(&nstring[l], " by ",4) == 0)  {
-                       nstring[l] = 0;
-                       break;
-               }
-               l --;
+       /* Eliminate leading whitespace in all cases */
+       while (ostring[0] && isspace(ostring[0])) {
+               /* If orig string has N bytes, we want to copy N-1 bytes
+                * of the string itself plus the string terminator (which 
+                * matters if the string consists of nothing but spaces) 
+                */
+               memmove(&ostring[0], &ostring[1], strlen(ostring));
        }
-       xfree(ostring);
-       ostring = nstring;
 
        if (!hdl->whitespaceok) {
                /* 
@@ -319,11 +328,23 @@ mkshort(void *h, const char *istring)
        for (i=0;i<l;i++) {
                if (strchr(hdl->badchars, tstring[i]) || !isascii(tstring[i]))
                        continue;
+               if (hdl->goodchars && (!strchr(hdl->goodchars, tstring[i])))
+                       continue;
                *cp++ = tstring[i];
        }
        *cp = 0;
        xfree(tstring);
 
+       /* 
+        * Eliminate repeated whitespace.  This can only shorten the string
+        * so we do it in place.
+        */
+       for (i = 0; i < l-1; i++) {
+               if (ostring[i] == ' ' && ostring[i+1] == ' ') {
+                       memmove(&ostring[i], &ostring[i+1], l-i);
+               }
+       }
+       
        /*
         * Toss vowels to approach target length, but don't toss them   
         * if we don't have to.  We always keep the leading two letters
@@ -351,7 +372,7 @@ mkshort(void *h, const char *istring)
         * Walk in the Woods 2.
         */
        np = ostring + strlen(ostring);
-       while (isdigit(*(np-1) )) {
+       while (*(np-1) && isdigit(*(np-1) )) {
                np--;
        }
        if (np) {
@@ -366,12 +387,47 @@ mkshort(void *h, const char *istring)
                strcpy(&ostring[hdl->target_len] - strlen(np), np);
        }
 
+       /* 
+        * If, after all that, we have an empty string, punt and
+        * let the must_uniq code handle it.
+        */
+       if (ostring[0] == '\0') {
+               xfree(ostring);
+               ostring = xstrdup("WPT");
+       }
+
        if (hdl->must_uniq) {
                return mkshort_add_to_list(hdl, ostring);
        }
        return ostring;
 }
 
+/*
+ * As above, but arg list is a waypoint so we can centralize
+ * the code that considers the alternate sources.
+ */
+char *
+mkshort_from_wpt(void *h, const waypoint *wpt)
+{
+       /* This probably came from a Groundspeak Pocket Query
+        * so use the 'cache name' instead of the description field
+        * which contains placer name, diff, terr, and generally way
+        * more stuff than should be in any one field...
+        */
+       if (wpt->gc_data.diff && wpt->gc_data.terr && wpt->notes) {
+               return mkshort(h, wpt->notes);
+       }
+
+       if (wpt->description) {
+               return mkshort(h, wpt->description);
+       }
+
+       if (wpt->notes) {
+               return mkshort(h, wpt->notes);
+       }
+}
+
+
 #if 0
 char *foo[] =  {
 "VwthPst# 3700.706N 08627.588W 0000000m View the Past #2              ",
index 5b1ab443dd99ad657023999a5f9b3ef990fe413b..45f765deebd525b1833aa708060aaabd246f3266 100644 (file)
@@ -39,9 +39,10 @@ RSC=rc.exe
 # PROP Use_Debug_Libraries 0
 # PROP Output_Dir "Release"
 # PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "expat" /I "..\coldsync" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__WIN32__" /D VERSION=\"1.2.1_beta01072004_msvc\" /YX /FD /c
+# ADD CPP /nologo /W3 /WX /GX /O2 /I "expat" /I "..\coldsync" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__WIN32__" /D VERSION=\"1.2.1_beta01072004_msvc\" /YX /FD /c
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
 # ADD RSC /l 0x409 /d "NDEBUG"
 BSC32=bscmake.exe
@@ -49,7 +50,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setupapi.lib /nologo /subsystem:console /machine:I386
 
 !ELSEIF  "$(CFG)" == "GPSBabel - Win32 Debug"
 
@@ -62,10 +63,10 @@ LINK32=link.exe
 # PROP Use_Debug_Libraries 1
 # PROP Output_Dir "Debug"
 # PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "expat" /I "..\coldsync" /D "WIN32" /D "__WIN32__" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D VERSION=\"1.2.1_beta01072004_msvc\" /FR /YX /FD /GZ /c
-# SUBTRACT CPP /WX
+# ADD CPP /nologo /W3 /WX /Gm /GX /ZI /Od /I "expat" /I "..\coldsync" /D "WIN32" /D "__WIN32__" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D VERSION=\"1.2.1_beta01072004_msvc\" /FR /YX /FD /GZ /c
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
 # ADD RSC /l 0x409 /d "_DEBUG"
 BSC32=bscmake.exe
@@ -73,7 +74,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setupapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
 
 !ENDIF 
 
@@ -224,6 +225,22 @@ SOURCE=..\jeeps\gpsserial.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\jeeps\gpsusbread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jeeps\gpsusbsend.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jeeps\gpsusbstub.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jeeps\gpsusbwin.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\jeeps\gpsutil.c
 
 !IF  "$(CFG)" == "GPSBabel - Win32 Release"
@@ -270,6 +287,18 @@ SOURCE=..\coldsync\util.c
 
 !ENDIF 
 
+# End Source File
+# End Group
+# Begin Group "ShapeLib"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\shapelib\dbfopen.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\shapelib\shpopen.c
 # End Source File
 # End Group
 # Begin Source File
@@ -278,10 +307,18 @@ SOURCE=..\arcdist.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\brauniger_iq.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\cetus.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\coastexp.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\copilot.c
 # End Source File
 # Begin Source File
@@ -310,6 +347,10 @@ SOURCE=..\garmin.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\garmin_tables.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\gcdb.c
 # End Source File
 # Begin Source File
@@ -322,6 +363,14 @@ SOURCE=..\geoniche.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\glogbook.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\google.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\gpilots.c
 # End Source File
 # Begin Source File
@@ -342,6 +391,10 @@ SOURCE=..\grtcirc.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\hiketech.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\holux.c
 # End Source File
 # Begin Source File
@@ -354,10 +407,22 @@ SOURCE=..\html.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\igc.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\internal_styles.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\kml.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lowranceusr.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\magnav.c
 # End Source File
 # Begin Source File
@@ -398,6 +463,10 @@ SOURCE=..\nmea.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\overlay.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\ozi.c
 # End Source File
 # Begin Source File
@@ -446,6 +515,10 @@ SOURCE=..\saroute.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\shape.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\smplrout.c
 # End Source File
 # Begin Source File
@@ -454,6 +527,10 @@ SOURCE=..\sort.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\stackfilter.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\text.c
 # End Source File
 # Begin Source File
@@ -478,6 +555,14 @@ SOURCE=..\util_crc.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\uuid.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vcf.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\vecs.c
 # End Source File
 # Begin Source File
@@ -494,6 +579,10 @@ SOURCE=..\xcsv.c
 # End Source File
 # Begin Source File
 
+SOURCE=..\xmlgeneric.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\Expat\libexpat.lib
 # End Source File
 # End Group
@@ -600,6 +689,14 @@ SOURCE=..\jeeps\gpsserial.h
 SOURCE=..\jeeps\gpsutil.h
 # End Source File
 # End Group
+# Begin Group "ShapeLib-Headers"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\shapelib\shapefil.h
+# End Source File
+# End Group
 # Begin Source File
 
 SOURCE=..\csv_util.h
@@ -636,6 +733,10 @@ SOURCE=..\queue.h
 
 SOURCE=..\quovadis.h
 # End Source File
+# Begin Source File
+
+SOURCE=..\uuid.h
+# End Source File
 # End Group
 # Begin Group "Resource Files"
 
index 8d9f72aea300cde24da007bee00fa1fd36049351..8d000a790d0fcddd12acef29944fbbc7ad43f5f4 100644 (file)
@@ -33,6 +33,7 @@
                                ObjectFile=".\Release/"
                                ProgramDataBaseFileName=".\Release/"
                                WarningLevel="3"
+                               WarnAsError="TRUE"
                                SuppressStartupBanner="TRUE"
                                DebugInformationFormat="3"
                                CompileAs="0"/>
@@ -40,6 +41,7 @@
                                Name="VCCustomBuildTool"/>
                        <Tool
                                Name="VCLinkerTool"
+                               AdditionalDependencies="setupapi.lib"
                                OutputFile=".\Release/GPSBabel.exe"
                                LinkIncremental="1"
                                SuppressStartupBanner="TRUE"
                                ProgramDataBaseFileName=".\Debug/"
                                BrowseInformation="1"
                                WarningLevel="3"
+                               WarnAsError="TRUE"
                                SuppressStartupBanner="TRUE"
-                               DebugInformationFormat="4"
+                               DebugInformationFormat="3"
                                CompileAs="0"/>
                        <Tool
                                Name="VCCustomBuildTool"/>
                        <Tool
                                Name="VCLinkerTool"
+                               AdditionalDependencies="setupapi.lib"
                                OutputFile=".\Debug/GPSBabel.exe"
                                LinkIncremental="1"
                                SuppressStartupBanner="TRUE"
                                                BrowseInformation="1"/>
                                </FileConfiguration>
                        </File>
+                       <File
+                               RelativePath="..\coastexp.c">
+                       </File>
                        <File
                                RelativePath="..\copilot.c">
                                <FileConfiguration
                                                BrowseInformation="1"/>
                                </FileConfiguration>
                        </File>
+                       <File
+                               RelativePath="..\glogbook.c">
+                       </File>
+                       <File
+                               RelativePath="..\google.c">
+                       </File>
                        <File
                                RelativePath="..\gpilots.c">
                                <FileConfiguration
                                                BrowseInformation="1"/>
                                </FileConfiguration>
                        </File>
+                       <File
+                               RelativePath="..\hiketech.c">
+                       </File>
                        <File
                                RelativePath="..\holux.c">
                                <FileConfiguration
                                                BrowseInformation="1"/>
                                </FileConfiguration>
                        </File>
+                       <File
+                               RelativePath="..\kml.c">
+                       </File>
                        <File
                                RelativePath="Expat\libexpat.lib">
                        </File>
+                       <File
+                               RelativePath="..\lowranceusr.c">
+                       </File>
                        <File
                                RelativePath="..\magnav.c">
                                <FileConfiguration
                                                BrowseInformation="1"/>
                                </FileConfiguration>
                        </File>
+                       <File
+                               RelativePath="..\overlay.c">
+                       </File>
                        <File
                                RelativePath="..\ozi.c">
                                <FileConfiguration
                                                BrowseInformation="1"/>
                                </FileConfiguration>
                        </File>
+                       <File
+                               RelativePath="..\shape.c">
+                       </File>
                        <File
                                RelativePath="..\smplrout.c">
                                <FileConfiguration
                                                BrowseInformation="1"/>
                                </FileConfiguration>
                        </File>
+                       <File
+                               RelativePath="..\stackfilter.c">
+                       </File>
                        <File
                                RelativePath="..\text.c">
                                <FileConfiguration
                                                BrowseInformation="1"/>
                                </FileConfiguration>
                        </File>
+                       <File
+                               RelativePath="..\uuid.c">
+                       </File>
+                       <File
+                               RelativePath="..\vcf.c">
+                       </File>
                        <File
                                RelativePath="..\vecs.c">
                                <FileConfiguration
                                                BrowseInformation="1"/>
                                </FileConfiguration>
                        </File>
+                       <File
+                               RelativePath="..\xmlgeneric.c">
+                       </File>
                        <Filter
                                Name="Jeeps"
                                Filter="">
                                                        BrowseInformation="1"/>
                                        </FileConfiguration>
                                </File>
+                               <File
+                                       RelativePath="..\jeeps\gpsusbread.c">
+                               </File>
+                               <File
+                                       RelativePath="..\jeeps\gpsusbsend.c">
+                               </File>
+                               <File
+                                       RelativePath="..\jeeps\gpsusbstub.c">
+                               </File>
+                               <File
+                                       RelativePath="..\jeeps\gpsusbwin.c">
+                               </File>
                                <File
                                        RelativePath="..\jeeps\gpsutil.c">
                                        <FileConfiguration
                                        </FileConfiguration>
                                </File>
                        </Filter>
+                       <Filter
+                               Name="shapelib"
+                               Filter="">
+                               <File
+                                       RelativePath="..\shapelib\dbfopen.c">
+                               </File>
+                               <File
+                                       RelativePath="..\shapelib\shpopen.c">
+                               </File>
+                       </Filter>
                </Filter>
                <Filter
                        Name="Header Files"
                                <File
                                        RelativePath="..\jeeps\gpsserial.h">
                                </File>
+                               <File
+                                       RelativePath="..\jeeps\gpsusbint.h">
+                               </File>
                                <File
                                        RelativePath="..\jeeps\gpsutil.h">
                                </File>
index 0d42a38bab8fa8cbd5851f03b1942fb86163d87f..eb134c21f4899251d15666a93467faf15933c122 100644 (file)
@@ -256,6 +256,7 @@ nav_write(void)
 
 ff_vecs_t navicache_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        nav_rd_init,    
        nav_wr_init,    
        nav_rd_deinit,
index 1674215e60187e6d0e976b64db07d2cee8163896..242fdb8815a2c1575f486a6b01f3f0511c2a901b 100644 (file)
@@ -293,6 +293,7 @@ fix_netstumbler_dupes(void)
 
 ff_vecs_t netstumbler_vecs = {
        ff_type_file,
+       { ff_cap_read, ff_cap_none, ff_cap_none },
        rd_init,
        NULL,
        rd_deinit,
diff --git a/nmea.c b/nmea.c
index 3b0f136ae4837def9465b55bb382b6bc72a72517..0a6fd3d686a64650b6cf4d42014ec73d3979ff89 100644 (file)
--- a/nmea.c
+++ b/nmea.c
@@ -439,7 +439,7 @@ nmea_trackpt_pr(const waypoint *wpt)
 }
 
 static void
-nmea_write()
+nmea_write(void)
 {
        waypt_disp_all(nmea_wayptpr);
        track_disp_all(NULL, NULL, nmea_trackpt_pr);
@@ -447,11 +447,13 @@ nmea_write()
 
 ff_vecs_t nmea_vecs = {
        ff_type_file,
+       { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_none},
        nmea_rd_init,   
        nmea_wr_init,   
        nmea_rd_deinit, 
        nmea_wr_deinit, 
        nmea_read,
        nmea_write,
+       NULL,
        NULL
 };
diff --git a/overlay.c b/overlay.c
new file mode 100644 (file)
index 0000000..aac9e5c
--- /dev/null
+++ b/overlay.c
@@ -0,0 +1,701 @@
+/*
+
+    Geogrid-Viewer overlay file  Version 0.9.3
+
+    A detail description of the ASCII-overlay-fomat you can find in the
+    helpfile of Geogrid-Viewer.
+
+    Latest changes at 11.01.2005 by Fredie Kern
+
+    Copyright (C) 2005 Fredie Kern, f.kern@xdesy.de
+
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+#include "defs.h"
+#include "grtcirc.h"
+
+static void *mkshort_handle;
+
+#define MYNAME         "overlay"
+#define PARAMETER_FILE "overlay.def"
+
+#undef  MAPNAME
+#define MAPNAME "Bundesrepublik 1:1 Mio"
+#undef  MAPNAME
+#define MAPNAME "Top. Karte 1:50.000 Nieders."
+
+static FILE *fpout;
+static FILE *fpin;
+static int govl_cnt;
+static double govl_sum_e=0.0;
+static double govl_sum_n=0.0;
+static double govl_sumcnt=0.0;
+static int    govl_symbol_cnt=0;
+static int    govl_group_cnt=0;
+/*
+static double govl_last_east=0.0;
+static double govl_last_north=0.0;
+*/
+
+static int     govl_col=1;
+static char   *govl_col_s = NULL;
+static int     govl_size=101;
+static char   *govl_size_s = NULL;
+static double  govl_dir=0.0;
+
+static char *govl_mapname = NULL;
+static int   govl_zoomfc = 100;
+static char *govl_zoomfc_s = NULL;
+static int   govl_dimmfc = 100;
+static char *govl_dimmfc_s = NULL;
+
+
+static int     govl_txtcol=1;
+static int     govl_txtsize=120;
+static int     govl_font=1;
+static int     govl_txttrans=0;
+
+static char *govl_txtcol_s = NULL;
+static char *govl_txtsize_s = NULL;
+static char *govl_font_s = NULL;
+static char *govl_txttrans_s = NULL;
+
+static char *govl_file_s = NULL;
+
+static arglist_t ovl_args[] = {
+       { "col", &govl_col_s, "color index [1-9] for routes",
+        NULL, ARGTYPE_INT },
+       { "size", &govl_size_s, "size index [101-] for routes",
+        NULL, ARGTYPE_INT },
+       { "mapname", &govl_mapname, "name of map",
+        NULL, ARGTYPE_STRING },
+       { "zoomfc", &govl_zoomfc_s, "zoom factor of map in %",
+        NULL, ARGTYPE_INT },
+       { "dimmfc", &govl_dimmfc_s, "dimmer factor of map in %",
+        NULL, ARGTYPE_INT },
+       { "txtcol", &govl_txtcol_s, "color index [1-9] for waypoint names",
+        NULL, ARGTYPE_INT },
+       { "txtsize", &govl_txtsize_s, "text size [101-] for waypoint names",
+        NULL, ARGTYPE_INT },
+       { "font", &govl_font_s, "font index [1-] for waypoint names",
+        NULL, ARGTYPE_INT },
+       { "txttrans", &govl_txttrans_s, "set text background to transparent",
+        NULL, ARGTYPE_BOOL },
+       { "file", &govl_file_s, "use file of parameters (parameters on command line overwrites file parameters)",
+        NULL, ARGTYPE_STRING },
+       { 0, 0, 0, 0, 0 }
+};
+
+
+static char *Keywords[]={
+                "Typ",
+                "Group",
+                "Col",
+                "Zoom",
+                "Size",
+                "Art",
+                "Punkte",
+                "Path",
+                "Dir",
+                "Font",
+                "Area",
+                "Text",
+                "Width",
+                "Height",
+                "Trans",
+                "TransByte",
+        NULL
+             };
+
+#define KEY_TYP        0
+#define KEY_GROUP      1
+#define KEY_COL        2
+#define KEY_ZOOM       3
+#define KEY_SIZE       4
+#define KEY_ART        5
+#define KEY_PUNKTE     6
+#define KEY_PATH       7
+#define KEY_DIR        8
+#define KEY_FONT       9
+#define KEY_AREA      10
+#define KEY_TEXT      11
+#define KEY_WIDTH     12
+#define KEY_HEIGHT    13
+#define KEY_TRANS     14
+#define KEY_TRANSBYTE 15
+
+static int isKeyword(char *str,char **keys)
+{
+  int i;
+
+  i = 0;
+  while(keys[i]!=NULL && strcmp(str,keys[i])) i++;
+  return(keys[i]==NULL ? -1 : i);
+}
+
+/*----------------------------------------------*/
+
+void ovl_rd_init(char const *fname)
+{
+  fpin = xfopen(fname, "rt", MYNAME);
+}
+
+#define SECTION_NONE    0
+#define SECTION_SYMBOL  1
+#define SECTION_PUNKTE  2
+#define SECTION_OVERLAY 3
+
+#define MAXLINE 512
+
+static  struct _group {
+                 int  group;
+                 char *name;
+                } *groups;
+static  int    groups_cnt;
+
+void ovl_add_group(int aktgrp,char *akttxt)
+{
+  int i;
+
+  i = 0;
+  while (i<groups_cnt && groups[i].group!=aktgrp) i++;
+  if (i==groups_cnt)
+  {
+    groups = (struct _group *) xrealloc(groups,(groups_cnt+1)*sizeof(struct _group));
+    groups[i].group = aktgrp;
+    groups[i].name = NULL;
+    groups_cnt++;
+  }
+  groups[i].name = (char *) xrealloc(groups[i].name,(strlen(akttxt)+1)*sizeof(char));
+  strcpy(groups[i].name,akttxt);
+}
+
+/*
+  The name of route is stored in a 'Text'-symbol with identical 'Group'-number.
+*/
+void route_add_name(const route_head *hd)
+{
+  int grp;
+  int i;
+  char name[MAXLINE];
+  route_head *route;
+
+  route = (route_head *) hd;
+  grp = atoi(route->rte_name);
+  i = 0;
+  while (i<groups_cnt && groups[i].group!=grp) i++;
+  if (i==groups_cnt) // not found
+  {
+    sprintf(name,"undef(%d)",grp); /* pseudo name*/
+    sprintf(name,"?%d",grp);
+  }
+  else
+  {
+    strcpy(name,groups[i].name);
+  }
+  route->rte_name = (char *) xrealloc(route->rte_name,(strlen(name)+1)*sizeof(char));
+  strcpy(route->rte_name,name);
+}
+
+void ovl_read(void)
+{
+  char    line[MAXLINE];
+  int     isSection;
+  int     aktTyp,aktCol,aktSize,aktArt,aktGroup;
+  int     aktArea,aktWidth,aktHeight,aktTrans,aktTransByte,aktDir;
+  double  aktX,aktY;
+  char   *aktPath;
+  char   *aktText;
+  char   *pstr;
+  int     keyw,i;
+  double  rwert;
+  route_head *route_head = NULL;
+  waypoint   *wpt;
+  int      sym_cnt;
+
+  groups = NULL;
+  groups_cnt = 0;
+  aktTyp = aktCol = aktSize = aktArt = aktGroup = -1;
+  aktArea = aktWidth = aktHeight = aktTrans = aktTransByte = aktDir = -1;
+  aktX = aktY = 0.0;
+  aktText = NULL;
+  aktPath = NULL;
+  sym_cnt = 0;
+  isSection = SECTION_NONE;
+  while (fgets(line,MAXLINE-1,fpin)!=NULL)
+  {
+    if( (pstr = strstr(line,"[Symbol "))!= NULL)
+    {
+      sym_cnt++;
+      isSection = SECTION_SYMBOL;
+    }
+    else if( (pstr = strstr(line,"[Overlay]"))!= NULL)
+    {
+      isSection = SECTION_OVERLAY;
+    }
+    else if (isSection==SECTION_SYMBOL)
+    {
+      pstr = strtok(line,"=");
+      if (pstr!=NULL)
+      {
+        keyw = isKeyword(pstr,Keywords);
+        pstr = strtok(NULL,"\n");
+        if (pstr!=NULL)
+        {
+          switch(keyw)
+          {
+            case KEY_TYP     :
+              aktTyp = atoi(pstr);
+              break;
+            case KEY_GROUP   :
+              aktGroup = atoi(pstr);
+              ovl_add_group(aktGroup,"?"); /* 'Group' without relation to 'Text'-Symbol */
+              switch(aktTyp)
+              {
+                case 3: // Linie
+                  route_head = route_head_alloc();
+                  route_head->rte_num = sym_cnt;
+                  route_head->rte_name = xstrdup(pstr); /* use group-number for the moment */
+                  route_add_head(route_head);
+                  break;
+              }
+              break;
+            case KEY_COL     :
+              aktCol = atoi(pstr);
+              break;
+            case KEY_ZOOM    :
+              break;
+            case KEY_SIZE    :
+              aktSize = atoi(pstr);
+              break;
+            case KEY_ART     :
+              aktArt = atoi(pstr);
+              break;
+            case KEY_AREA     :
+              aktArea = atoi(pstr);
+              if (aktTyp==5 || aktTyp==5 || aktTyp==7) isSection = SECTION_PUNKTE; // Rechteck, Kreis, Dreieck
+              break;
+            case KEY_PUNKTE  :
+              isSection = SECTION_PUNKTE; // Linie, Fläche
+              break;
+#ifdef WITH_BITMAP
+            case KEY_PATH     :
+              aktPath = xstrdup(pstr);
+              isSection = SECTION_PUNKTE; // Bitmap
+              break;
+            case KEY_TRANS     :
+              aktTrans = atoi(pstr);
+              break;
+            case KEY_TRANSBYTE     :
+              aktTransByte = atoi(pstr);
+              break;
+#endif
+            case KEY_TEXT     :
+              aktText = xstrdup(pstr);
+              /* The last 'Text'-symbol wins as a information block for
+                 waypoint/route description.
+                 Infos from previous symbols get overwrited.
+              */
+              ovl_add_group(aktGroup,aktText);
+              break;
+            case KEY_WIDTH     :
+              aktWidth = atoi(pstr);
+              break;
+            case KEY_HEIGHT     :
+              aktHeight = atoi(pstr);
+              break;
+            case KEY_DIR     :
+              aktDir = atoi(pstr);
+              if (aktTyp==2) isSection = SECTION_PUNKTE; // Text
+              break;
+          }
+        }
+      }
+    }
+    else if (isSection==SECTION_PUNKTE)
+    {
+      pstr = strtok(line,"=");
+      if (strstr(pstr,"XKoord")!=NULL || strstr(pstr,"YKoord")!=NULL)
+      {
+        if ((pstr = strtok(NULL,"\n"))!=NULL)
+        {
+          rwert = atof(pstr);
+          if (line[0]=='X')
+          {
+            aktX = rwert;
+          }
+          else if (line[0]=='Y')
+          {
+            aktY = rwert;
+            switch(aktTyp)
+            {
+#ifdef WITH_BITMAP
+              case 1: // Bitmap
+                wpt = waypt_new();
+                wpt->latitude = aktY;
+                wpt->longitude = aktX;
+                wpt->altitude = 0.0;
+                wpt->shortname = strdup(aktPath);
+                waypt_add(wpt);
+                break;
+#endif
+              case 2: // Text
+                isSection = SECTION_SYMBOL;
+                break;
+              case 3: // Linie
+                wpt = waypt_new();
+                wpt->latitude = aktY;
+                wpt->longitude = aktX;
+                wpt->altitude = 0.0;
+                route_add_wpt(route_head, wpt);
+                break;
+              case 4: // Fläche
+                break;
+              case 5: // Rechteck
+                break;
+              case 6: // Kreis
+                break;
+              case 7: // Dreieck
+                break;
+            }
+          }
+        }
+      }
+    }
+    else if (isSection==SECTION_OVERLAY)
+    {
+      isSection = SECTION_NONE;
+    }
+  }
+  route_disp_all(route_add_name,NULL,NULL);
+  if (aktText!=NULL) xfree(aktText);
+  if (aktPath!=NULL) xfree(aktPath);
+  for (i=0;i<groups_cnt;i++)
+  {
+    if (groups[i].name!=NULL) xfree(groups[i].name);
+  }
+  xfree(groups);
+}
+
+void ovl_rd_deinit(void)
+{
+  fclose(fpin);
+}
+
+/*------------------------------------------*/
+void ovl_read_parameter(char *fname)
+{
+  FILE      *fpin;
+  arglist_t *p;
+  char       line[MAXLINE],str[MAXLINE];
+  char      *pstr;
+
+  fpin = fopen(fname,"rt");
+  if (fpin!=NULL)
+  {
+    while (fgets(line,MAXLINE-1,fpin)!=NULL)
+    {
+      sscanf(line,"%s",str); // trim
+      if (str[0]!=';')
+      {
+        p = ovl_args;
+        pstr = strtok(line,"=");
+        if (pstr!=NULL)
+        {
+          while(p->argstring!=NULL)
+          {
+            if (strcmp(pstr,p->argstring)==0)
+            {
+              pstr = strtok(NULL,"\n");
+              if (p->argtype==ARGTYPE_BOOL)
+              {
+                *(p->argval) = atoi(pstr) ? strdup(pstr) : NULL;
+              }
+              else
+              {
+                *(p->argval) = strdup(pstr);
+              }
+              break;
+            }
+            p++;
+          }
+        }
+      }
+    }
+    fclose(fpin);
+  }
+}
+
+void ovl_wr_init(const char *fname)
+{
+  fpout = xfopen(fname, "wt", MYNAME);
+  govl_sum_n = 0.0;
+  govl_sum_e = 0.0;
+  govl_sumcnt = 0.0;
+  govl_symbol_cnt = 0;
+
+
+  ovl_read_parameter(govl_file_s!=NULL ? govl_file_s : PARAMETER_FILE);
+
+  if (govl_col_s!=NULL)
+  {
+    govl_col = atoi(govl_col_s);
+  }
+  if (govl_size_s!=NULL)
+  {
+    govl_size = atoi(govl_size_s);
+  }
+  if (govl_mapname==NULL)
+  {
+    govl_mapname = xstrdup(MAPNAME);
+  }
+  if (govl_zoomfc_s!=NULL)
+  {
+    govl_zoomfc = atoi(govl_zoomfc_s);
+  }
+  if (govl_dimmfc_s!=NULL)
+  {
+    govl_dimmfc = atoi(govl_dimmfc_s);
+  }
+  if (govl_txtcol_s!=NULL)
+  {
+    govl_txtcol = atoi(govl_txtcol_s);
+  }
+  if (govl_txtsize_s!=NULL)
+  {
+    govl_txtsize = atoi(govl_txtsize_s);
+  }
+  if (govl_font_s!=NULL)
+  {
+    govl_font = atoi(govl_font_s);
+  }
+  if (govl_txttrans_s!=NULL)
+  {
+    govl_txttrans = 1;
+  }
+}
+
+void ovl_wr_deinit(void)
+{
+  fprintf(fpout,"[Overlay]\n");
+  fprintf(fpout,"Symbols=%d\n",govl_symbol_cnt);
+  fprintf(fpout,"[MapLage]\n");
+  fprintf(fpout,"MapName=%s\n",govl_mapname);
+  fprintf(fpout,"DimmFc=%d\n",govl_dimmfc);
+  fprintf(fpout,"ZoomFc=%d\n",govl_zoomfc);
+  if (govl_symbol_cnt)
+  {
+    fprintf(fpout,"CenterLat=%.8lf\n",govl_sum_n/govl_sumcnt); // precision 8 = better than 1mm
+    fprintf(fpout,"CenterLong=%.8lf\n",govl_sum_e/govl_sumcnt);
+  }
+  else
+  {
+    fprintf(fpout,"CenterLong=10.52374295\n"); // Braunschweiger Löwe, Mittelpunkt der Welt :-)
+    fprintf(fpout,"CenterLat=52.26474445\n");
+  }
+  fprintf(fpout,"RefOn=0\n");
+
+  fclose(fpout);
+}
+
+void symbol_init(const route_head *hd)
+{
+  fprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1);
+  fprintf(fpout,"Typ=3\n");                            // Linie
+  fprintf(fpout,"Group=%d\n"   ,govl_group_cnt+1+1);   // group==1 : not a group
+  fprintf(fpout,"Col=%d\n"     ,govl_col);
+  fprintf(fpout,"Zoom=2\n");
+  fprintf(fpout,"Size=%d\n"    ,govl_size);
+  fprintf(fpout,"Art=1\n");
+  fprintf(fpout,"Punkte=%d\n"  ,hd->rte_waypt_ct);
+  govl_cnt = 0;
+  govl_symbol_cnt++;
+  govl_group_cnt++;
+}
+
+void symbol_text(double east,double north,char *text,int group)
+{
+  fprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1);
+  fprintf(fpout,"Typ=2\n");                           // Text
+  fprintf(fpout,"Group=%d\n",group+1);  // group==1 : not a group
+  fprintf(fpout,"Col=%d\n",govl_txtcol);
+  fprintf(fpout,"Area=%d\n",govl_txttrans ? 1 : 2); // =2 opak =1 transparent
+  fprintf(fpout,"Zoom=%d\n",2);
+  fprintf(fpout,"Size=%d\n",govl_txtsize);
+  fprintf(fpout,"Font=%d\n",govl_font);
+  fprintf(fpout,"Dir=%d\n",100+((int) govl_dir));
+  fprintf(fpout,"XKoord=%.8lf\n",east);  // precision 8 = better than 1mm
+  fprintf(fpout,"YKoord=%.8lf\n",north);
+  fprintf(fpout,"Text=%s\n",text);
+  govl_symbol_cnt++;
+}
+
+void symbol_point(const waypoint *wpt)
+{
+  double east,north;
+
+  east  = wpt->longitude;
+  north = wpt->latitude;
+  fprintf(fpout,"XKoord%d=%.8lf\n",govl_cnt,east);    // precision 8 = better than 1mm
+  fprintf(fpout,"YKoord%d=%.8lf\n",govl_cnt,north);
+  govl_cnt++;
+  govl_sum_e += east;
+  govl_sum_n += north;
+  govl_sumcnt += 1.0;
+/*
+  govl_last_east  = east;
+  govl_last_north = north;
+*/
+}
+
+
+void symbol_deinit(const route_head *hd)
+{
+  queue *elem, *tmp;
+  waypoint *waypointp;
+  int i;
+  double lat1,lon1,lat2,lon2;
+  double lats,lons,late,lone;
+  double dist,d,dd;
+
+  lat1 = lon1 = lat2 = lon2 = 0.0;
+  lats = lons = late = lone = 0.0;
+  dist = 0.0;
+  i = 0;
+  QUEUE_FOR_EACH(&(hd->waypoint_list), elem, tmp)
+  {
+    waypointp = (waypoint *) elem;
+    lat2 = waypointp->latitude *M_PI/180.0 ;
+    lon2 = waypointp->longitude*M_PI/180.0 ;
+    if (i)
+    {
+      d   = gcdist(lat1, lon1, lat2, lon2 );
+      dist += d;
+    }
+    else
+    {
+      lats = lat2; // start point
+      lons = lon2;
+    }
+    lat1 = lat2;
+    lon1 = lon2;
+    i++;
+  }
+  late = lat2;  // end point
+  lone = lon2;
+  dd = 0;
+  i = 0;
+  elem = QUEUE_FIRST(&(hd->waypoint_list));
+  while (elem!=&(hd->waypoint_list) && dd<dist/2.0)
+  {
+    waypointp = (waypoint *) elem;
+    lat2 = waypointp->latitude *M_PI/180.0;
+    lon2 = waypointp->longitude*M_PI/180.0;
+    if (i)
+    {
+      d   = gcdist(lat1, lon1, lat2, lon2 );
+      dd += d;
+    }
+    lat1 = lat2;
+    lon1 = lon2;
+    elem = QUEUE_NEXT(elem);
+    i++;
+  }
+
+  d = gcdist(lats,lons,late,lone);
+//  d = acos( sin(lats)*sin(late)+cos(lats)*cos(late)*cos(lone-lons) );
+  dd = acos( (sin(late) - sin(lats)*cos(d))/(cos(lats)*sin(d)) );
+  if (lone<lons) dd = -dd;   // correction because the ambiguity of acos function
+  dd = dd * 180.0/M_PI;      // azimuth
+  dd = 360.0 - (dd + 270.0); // make it anticlockwise and start counting on x-axis
+  dd = dd <   0.0 ? dd + 360.0 : dd; // normalizing
+  dd = dd > 360.0 ? dd - 360.0 : dd; // normalizing
+
+  /* name of route */
+  /* plot text at the last point of route */
+  govl_dir = dd;  // approximated text rotation, correct value must be the azimuth in UTM
+  symbol_text(lon1*180.0/M_PI,lat1*180.0/M_PI,hd->rte_name,govl_group_cnt);
+  govl_dir = 0.0; // restore
+}
+
+static void overlay_waypt_pr(const waypoint *waypointp)
+{
+  const char *oname;
+  char *odesc;
+
+  /*
+   * Desparation time, try very hard to get a good shortname
+  */
+  odesc = waypointp->notes;
+  if (!odesc) {
+    odesc = waypointp->description;
+  }
+  if (!odesc) {
+    odesc = waypointp->shortname;
+  }
+  oname = global_opts.synthesize_shortnames ?
+              mkshort(mkshort_handle, odesc) :
+              waypointp->shortname;
+
+  fprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1);
+  fprintf(fpout,"Typ=1\n");
+  fprintf(fpout,"Group=1\n");
+  fprintf(fpout,"Width=100\n");
+  fprintf(fpout,"Height=100\n");
+  fprintf(fpout,"Dir=%d\n",100+((int) govl_dir));
+  fprintf(fpout,"Zoom=2\n");
+  fprintf(fpout,"Trans=2\n");
+  fprintf(fpout,"TransByte=5\n");
+  fprintf(fpout,"Path=%s\n","waypoint.bmp");
+  fprintf(fpout,"XKoord=%.8lf\n",waypointp->longitude);
+  fprintf(fpout,"YKoord=%.8lf\n",waypointp->latitude);
+  govl_symbol_cnt++;
+  govl_sum_e += waypointp->longitude;
+  govl_sum_n += waypointp->latitude;
+  govl_sumcnt += 1.0;
+
+}
+
+void ovl_write(void)
+{
+  waypt_disp_all(overlay_waypt_pr);
+  track_disp_all(symbol_init, symbol_deinit, symbol_point);
+  route_disp_all(symbol_init, symbol_deinit, symbol_point);
+/*
+  switch(global_opts.objective)
+  {
+    case wptdata:
+      break;
+    case trkdata:
+      break;
+  }
+*/
+}
+
+
+ff_vecs_t overlay_vecs = {
+       ff_type_internal,
+       FF_CAP_RW_ALL,
+       ovl_rd_init,
+       ovl_wr_init,
+       ovl_rd_deinit,
+       ovl_wr_deinit,
+       ovl_read,
+       ovl_write,
+        NULL,
+       ovl_args
+};
diff --git a/ozi.c b/ozi.c
index ff9487571706a5a35174feca17155aca4ab28d4a..b655f61a2c6a926561d1aadcb0bc112c2bedbf14 100644 (file)
--- a/ozi.c
+++ b/ozi.c
@@ -4,7 +4,7 @@
 
     As described in OziExplorer Help File
 
-    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+    Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -548,6 +548,13 @@ data_read(void)
                 ozi_objective = wptdata;
             }
         }
+
+        if (linecount == 2) {
+           if (case_ignore_strncmp(buff, "WGS 84", 6)) {
+               warning(MYNAME "Only supports reading WGS 84 datum, not '%s'\n", buff);
+           }
+       }
+
         if ((strlen(buff)) && (strstr(buff, ",") != NULL)) {
 
             wpt_tmp = waypt_new();
@@ -626,7 +633,7 @@ ozi_waypt_pr(const waypoint * wpt)
     if ((!wpt->shortname) || (global_opts.synthesize_shortnames)) {
         if (wpt->description) {
             if (global_opts.synthesize_shortnames)
-                shortname = mkshort(mkshort_handle, wpt->description);
+                shortname = mkshort_from_wpt(mkshort_handle, wpt);
             else
                 shortname = csv_stringclean(wpt->description, ",");
         } else {
@@ -692,6 +699,7 @@ data_write(void)
 
 ff_vecs_t ozi_vecs = {
     ff_type_file,
+    FF_CAP_RW_ALL,
     rd_init,
     wr_init,
     rd_deinit,
index 40cf79b003c554b2e20b6a333daee3a18d0b3a9d..5e82f5aea393bdb9b7c5393bdc26c2951541dd6c 100644 (file)
--- a/palmdoc.c
+++ b/palmdoc.c
@@ -256,7 +256,8 @@ static void write_header( void ) {
                --recs;
        }
        
-       opdb_rec = new_Record (0, 0, 0, sizeof(struct doc_record0)+sizeof(short)*(ct-1), (const ubyte *)rec0);
+       opdb_rec = new_Record (0, 0, 0, 
+               (uword) (sizeof(struct doc_record0)+sizeof(short)*(ct-1)), (const ubyte *)rec0);
 
        if (opdb_rec == NULL) {
                fatal(MYNAME ": libpdb couldn't create summary record\n");
@@ -265,6 +266,7 @@ static void write_header( void ) {
        if (pdb_InsertRecord(opdb, NULL, opdb_rec)) {
                fatal(MYNAME ": libpdb couldn't insert summary record\n");
        }
+       xfree(rec0);
 }
 
 static void write_bookmarks( void ) {
@@ -302,7 +304,6 @@ static void write_bookmarks( void ) {
                        fatal(MYNAME ": libpdb couldn't append bookmark record\n");
                }
 
-               
                xfree( oldmark );
        } 
 }
@@ -316,7 +317,7 @@ static void commit_buffer( void ) {
 
        compress( &buf );
        
-        opdb_rec = new_Record (0, 0, ct++, buf.len, (const ubyte *)buf.data);
+        opdb_rec = new_Record (0, 0, ct++, (uword) buf.len, (const ubyte *)buf.data);
 
         if (opdb_rec == NULL) {
                 fatal(MYNAME ": libpdb couldn't create record\n");
@@ -414,26 +415,30 @@ palmdoc_disp(const waypoint *wpt)
        int latint, lonint;
        char tbuf[1024];
        time_t tm = wpt->creation_time;
-       long utmz;
+       int32 utmz;
        double utme, utmn;
        char utmzc;
+       char *bm;
 
         char bookmarktext[17];
 
         if ( bmid ) {
+               char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt);
                sprintf( bookmarktext, "%6s:%9s", 
-                       wpt->shortname?wpt->shortname:"",
-                       mkshort(mkshort_bookmark_handle, wpt->description));
+                       wpt->shortname?wpt->shortname:"",s);
+               xfree(s);
        }
        else {
-               sprintf( bookmarktext, "%16s", 
-                       mkshort(mkshort_bookmark_handle, wpt->description));
+               char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt);
+               sprintf( bookmarktext, "%16s", s);
+               xfree(s);
        }       
-       
-        create_bookmark(xstrdup(bookmarktext)); 
+
+        bm = xstrdup(bookmarktext); 
+        create_bookmark(bm);
        
-       lonint = abs(wpt->longitude);
-       latint = abs(wpt->latitude);
+       lonint = abs((int) wpt->longitude);
+       latint = abs((int) wpt->latitude);
 
        GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, 
                &utme, &utmn, &utmz, &utmzc);
@@ -443,7 +448,7 @@ palmdoc_disp(const waypoint *wpt)
        strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm));
 
        docprintf(300, "%-16s  %c%d %06.3f  %c%d %06.3f  (%ld%c %6.0f %7.0f)",
-               (global_opts.synthesize_shortnames) ? mkshort(mkshort_handle, wpt->description) : wpt->shortname,
+               (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname,
                wpt->latitude < 0 ? 'S' : 'N',  abs(latint), 60.0 * (fabs(wpt->latitude) - latint), 
                wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint),
                utmz, utmzc, utme, utmn);
@@ -604,6 +609,7 @@ data_write(void)
 
 ff_vecs_t palmdoc_vecs = {
        ff_type_file,
+       { ff_cap_write, ff_cap_none, ff_cap_none},
        NULL,
        wr_init,
        NULL,
diff --git a/pathaway.c b/pathaway.c
new file mode 100644 (file)
index 0000000..e3af372
--- /dev/null
@@ -0,0 +1,631 @@
+/* 
+       Support for PathAway Palm Database, 
+       Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+*/
+
+/* ToDo:
+       --- date format for read database --
+*/
+
+#include "defs.h"
+#include "coldsync/palm.h"
+#include "coldsync/pdb.h"
+#include "csv_util.h"
+
+#define MYNAME "PathAway pdb"
+
+#define PPDB_MAGIC_TRK 0x55735472              /* UsTr */
+#define PPDB_MAGIC_WPT  0x506f4c69             /* PoLi */
+#define PPDB_MAGIC     0x4b6e5772              /* KwNr */
+
+FILE *fd_in, *fd_out;
+struct pdb *pdb_in, *pdb_out;
+char *fname_in, *fname_out;
+static gpsdata_type ppdb_type;
+
+typedef struct ppdb_appdata
+{
+       unsigned char reservedA[274];           /* all 0 */
+       unsigned char dirtyFlag;
+       unsigned char dataBaseSubType;          /* 0 = Track, 1 = Route */
+       short int dbAttributes;                 /* 0 */
+       char vehicleStr[100];
+       unsigned char reservedB[100];           /* all 0 */
+} ppdb_appdata_t;
+
+#define PPDB_APPINFO_SIZE sizeof(struct ppdb_appdata)
+
+static char *date_fmt = NULL;
+static char *dbname = NULL;
+static char *deficon = NULL;
+
+static arglist_t ppdb_args[] = 
+{
+       {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING},
+       {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING},
+/*     {"dtfmt", &date_fmt, "Date format", NULL, ARGTYPE_STRING },             ToDo */
+       {0, 0, 0, 0 }
+};
+
+static void 
+is_fatal(int is, const char *msg, ... )
+{
+    if (is) fatal(MYNAME ": %s\n", msg);
+}
+
+#define CHECK_INP(i, j) is_fatal((i != j), "Error in data structure.")
+
+/*
+ * utilities
+ */
+
+char *ppdb_strcat(char *dest, char *src, char *def, int *size)
+{
+       int len;
+       char *res, *tmp;
+       
+       tmp = src;
+       if (tmp == NULL)
+       {
+           tmp = def;
+           if (tmp == NULL) return dest;
+       }
+       if (*tmp == '\0') return dest;
+       
+       len = strlen(dest) + strlen(tmp) + 1;
+       if (len > *size)
+       {
+           *size = len;
+           res = xrealloc(dest, *size);    
+       }
+       else
+           res = dest;
+       strcat(res, tmp);
+       return res;
+}
+
+#define STR_POOL_SIZE 16       /* !!! any power of 2 !!! */
+
+static char *str_pool[STR_POOL_SIZE] = {};
+static size_t str_pool_s[STR_POOL_SIZE] = {};
+static int str_poolp = -1;
+
+void str_pool_init(void)
+{
+       int i;
+       for (i = 0; i < STR_POOL_SIZE; i++)
+       {
+           str_pool[i] = NULL;
+           str_pool_s[i] = 0;
+       }
+}
+
+void str_pool_deinit(void)
+{
+       int i;
+       
+       for (i = 0; i < STR_POOL_SIZE; i++)
+           if ( str_pool_s[i] != 0 )
+           {
+               xfree(str_pool[i]);
+               str_pool[i] = NULL;
+               str_pool_s[i] = 0;
+           }
+}
+
+char *str_pool_get(size_t size)
+{
+       char *tmp;
+       
+       str_poolp = ((str_poolp + 1) & (STR_POOL_SIZE - 1));
+       tmp = str_pool[str_poolp];
+       
+       if (str_pool_s[str_poolp] == 0)
+           tmp = xmalloc(size);
+       else if (str_pool_s[str_poolp] < size)
+           tmp = xrealloc(tmp, size);
+       else
+           return tmp;
+           
+       str_pool[str_poolp] = tmp;
+       str_pool_s[str_poolp] = size;
+       
+       return tmp;
+}
+
+char *str_pool_getcpy(char *src, char *def)
+{
+       char *res;
+
+       if (src == NULL)
+       {
+           src = def;
+           if (src == NULL) src = "";
+       }
+       res = str_pool_get(strlen(src) + 1);
+       strcpy(res, src);
+
+       return res;
+}
+
+/*
+ * decoding/formatting functions
+ */
+char *ppdb_fmt_float(const double val)
+{
+       char *c;
+       char *str = str_pool_get(32);
+       snprintf(str, 32, "%.8f", val);
+       c = str + strlen(str) - 1;
+       while ((c > str) && (*c == '0'))
+       {
+           *c = '\0';
+           c--;
+           if (*c == '.')
+           {
+               c++;
+               *c = '0';
+               break;
+           }
+       }
+       return str;
+}
+
+char *ppdb_fmt_degrees(char dir, double val)
+{
+       char *tmp;
+       char *str = str_pool_get(32);
+       int deg = abs(val);
+       double min = 60.0 * (fabs(val) - deg);
+       int power = 0;
+       double fx = min;
+       while (fx > 1.0)
+       {
+           fx = fx / 10.0;
+           power++;
+       }
+       snprintf(str, 31, "%c%02d 000", dir, deg);
+       snprintf(str + 6 - power, 24, "%.8f", min);
+       
+       tmp = str + strlen(str) - 1;    /* trim trailing nulls */
+       while ((tmp > str) && (*tmp == '0'))
+       {
+           *tmp = '\0';
+           tmp--;
+           if (*tmp == '.')
+           {
+               tmp++;
+               *tmp = '0';
+               break;
+           }
+       }
+       return str;
+}
+
+double ppdb_decode_coord(const char *str)
+{
+       double val;
+       int deg;
+       char dir;
+       
+       if (*str < 'A')         /* only numeric */
+       {
+           CHECK_INP(1, sscanf(str,"%lf", &val));
+           return val;
+       }
+       else
+       {
+           char *tmp = strchr(str, ' ');
+           if ((tmp) && (tmp - str < 4))
+           {
+               CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, &deg, &val));
+               val = deg + (val / 60.0);
+           }
+           else
+           {
+               CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val));
+           }
+           if ((dir == 'S') || (dir == 'W'))
+               val = -val;
+       }
+       return val;
+}
+
+int ppdb_decode_tm(char *str, struct tm *tm)
+{
+       int i = 3;
+       int msec, d1, d2, d3, d4, year;
+       time_t tnow;
+       struct tm now;
+    
+       if (*str == '\0') return 0;     /* empty date and time */
+
+       if (strchr(str, '.'))           /* time in hhmmss.ms */
+       {
+           CHECK_INP(8, sscanf(str, "%02d%02d%02d.%d %02d%02d%02d%02d",
+               &tm->tm_hour, &tm->tm_min, &tm->tm_sec,
+               &msec, &d1, &d2, &d3, &d4));
+       }
+       else
+       {
+           CHECK_INP(7, sscanf(str, "%02d%02d%02d %02d%02d%02d%02d",
+               &tm->tm_hour, &tm->tm_min, &tm->tm_sec,
+               &d1, &d2, &d3, &d4));
+       }
+
+       tnow = current_time();
+       now = *localtime(&tnow);
+       now.tm_year += 1900;
+       now.tm_mon++;
+       
+       year = (d1 * 100) + d2;
+       
+       /* next code works for most, except for 19. and 20. of month */
+       /* for trouble use input date format - !!! ToDo !!! */
+       
+       if ((year < 1980) || (year > now.tm_year))                      /* YYYYMMDD or DDMMYYY ????? */
+       {
+           tm->tm_year = (d3 * 100) + d4;
+           tm->tm_mon = d2;
+           tm->tm_mday = d1;
+       }
+       else
+       {
+           tm->tm_year = (d1 * 100) + d2;
+           tm->tm_mon = d3;
+           tm->tm_mday = d4;
+       }
+       
+       return 1;
+}
+
+static int ppdb_read_wpt(const struct pdb *pdb_in, const struct pdb_record *pdb_rec, route_head *head)
+{
+       char *data, *str, *tmp;
+       char latdir, longdir;
+       int latdeg, longdeg, i;
+       double latval, longval, altfeet;
+       struct tm tm;
+       
+       for (pdb_rec = pdb_in->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) 
+       {
+               int line = 0;
+               waypoint *wpt_tmp = waypt_new();
+               data = (char *) pdb_rec->data;
+               
+               str = csv_lineparse(data, ",", """", line++);
+               while (str != NULL)
+               {
+                   switch(line)
+                   {
+                       case 1:
+                           wpt_tmp->latitude = ppdb_decode_coord(str);
+                           break;
+                       case 2:
+                           wpt_tmp->longitude = ppdb_decode_coord(str);
+                           break;
+                       case 3:
+                           if (*str != '\0')
+                           {
+                               CHECK_INP(1, sscanf(str, "%lf", &altfeet));
+                               if (altfeet != -9999) 
+                                   wpt_tmp->altitude = altfeet / 3.2808;
+                           }
+                           break;
+                       case 4:
+                           memset(&tm, 0, sizeof(tm));
+                           if (ppdb_decode_tm(str, &tm))
+                           {
+                               tm.tm_year -= 1900;
+                               tm.tm_mon--;
+                               wpt_tmp->creation_time = mktime(&tm) + get_tz_offset();
+                           }
+                           break;
+                       case 5:
+                           if (*str != '\0')
+                               wpt_tmp->shortname = xstrdup(str);
+                           break;
+                       case 6:         /* icon, ignore */
+                           break;
+                       case 7:
+                           if (*str != '\0')
+                               wpt_tmp->notes = xstrdup(str);
+                           break;
+                           
+                   }
+                   str = csv_lineparse(NULL, ",", """", line++);
+               }
+               
+               if (head)
+                   route_add_wpt(head, wpt_tmp);
+               else
+                   waypt_add(wpt_tmp);
+
+       } 
+       return 0;
+}
+
+/* ============================================================================================
+ * &&& gobal callbacks &&&
+ * ----------------------------------------------------------------------------------------- */
+
+static void ppdb_rd_init(const char *fname)
+{
+       fname_in = xstrdup(fname);
+       str_pool_init();
+       fd_in = xfopen(fname, "rb", MYNAME);
+       
+}
+
+static void ppdb_rd_deinit(void)
+{
+       fclose(fd_in);
+       str_pool_deinit();
+       xfree(fname_in);
+}
+
+static void ppdb_read(void)
+{
+       struct pdb_record *pdb_rec;
+       ppdb_appdata_t *info = NULL;
+       route_head *track_head, *route_head;
+       const char *descr = NULL;
+
+       if (NULL == (pdb_in = pdb_Read(fileno(fd_in))))
+           fatal(MYNAME ": pdb_Read failed.\n");
+           
+       if (pdb_in->creator != PPDB_MAGIC)      /* identify the database */
+           fatal(MYNAME ": Not a PathAway pdb file.\n");
+
+       if (pdb_in->version != 3)       /* Currently we support only version 3 */
+           fatal(MYNAME ": This file is from an untested version (%d) of PathAway and is unsupported.\n", pdb_in->version);
+
+       if ((pdb_in->appinfo_len > 0) && (pdb_in->appinfo != NULL))
+       {
+           info = (ppdb_appdata_t *) pdb_in->appinfo;
+           descr = info->vehicleStr;
+       }
+       
+       switch(pdb_in->type)
+       {
+           case PPDB_MAGIC_TRK:
+               ppdb_type = trkdata; /* as default */
+               if (info)
+               {
+                   switch(info->dataBaseSubType)
+                   {
+                       case 0: 
+                           ppdb_type = trkdata;
+                           break;
+                       case 1: 
+                           ppdb_type = rtedata;
+                           break;
+                       default:
+                           fatal(MYNAME": Invalid database subtype.\n");
+                   }
+               }
+               break;
+               
+           case PPDB_MAGIC_WPT:
+               ppdb_type = wptdata;
+               break;
+               
+           default:
+               fatal(MYNAME ": It looks like a PathAway pdb, but has no gps magic.\n");
+       }
+
+       switch(ppdb_type)
+       {
+           case trkdata:
+               track_head = route_head_alloc();
+               track_add_head(track_head);
+               track_head->rte_name = xstrdup(pdb_in->name);
+               ppdb_read_wpt(pdb_in, pdb_rec, track_head);
+               break;
+           case rtedata:
+               route_head = route_head_alloc();
+               route_add_head(route_head);
+               route_head->rte_name = xstrdup(pdb_in->name);
+               ppdb_read_wpt(pdb_in, pdb_rec, route_head);
+               break;
+           case wptdata:
+               ppdb_read_wpt(pdb_in, pdb_rec, NULL);
+               break;
+       }
+       
+       free_pdb(pdb_in);
+}
+
+/* ============================================================================================
+ *   PPDB: Write support
+ * -------------------------------------------------------------------------------------------*/
+
+static void ppdb_wr_init(const char *fname)
+{
+       fname_out = xstrdup(fname);
+       str_pool_init();
+       fd_out = xfopen(fname, "wb", MYNAME);
+}
+
+static void ppdb_wr_deinit(void)
+{
+       fclose(fd_out);
+       str_pool_deinit();
+       xfree(fname_out);
+}
+
+/*
+ * ppdb_write_wpt: callback for waypoint output
+ */ 
+#define REC_SIZE 128
+
+static void ppdb_write_wpt(const waypoint *wpt)
+{
+       char *buff, *tmp;
+       char latdir, longdir;
+       int latdeg, longdeg, len;
+       struct pdb_record *rec;
+       static int ct;
+       struct tm tm;
+       
+       buff = xmalloc(REC_SIZE);
+       memset(buff, 0, REC_SIZE);
+
+       if (wpt->latitude < 0)
+           latdir = 'S';
+       else
+           latdir = 'N';
+       if (wpt->longitude < 0)
+           longdir = 'W';
+       else
+           longdir = 'E';
+
+       snprintf(buff, REC_SIZE, "%s,%s,", 
+           ppdb_fmt_degrees(latdir, wpt->latitude),
+           ppdb_fmt_degrees(longdir, wpt->longitude)
+       );
+       
+       len = REC_SIZE;         /* we have coordinates in buff, now optional stuff */
+       
+       if (fabs(wpt->altitude) < 9999.0)       
+       {
+           tmp = str_pool_get(32);
+           snprintf(tmp, 32, ppdb_fmt_float(wpt->altitude * 3.2808));
+           buff = ppdb_strcat(buff, tmp, NULL, &len);
+       }
+       buff = ppdb_strcat(buff, ",", NULL, &len);
+       if ( wpt->creation_time != 0)
+       {
+           tmp = str_pool_get(20);
+           tm = *gmtime(&wpt->creation_time);
+           strftime(tmp, 20, "%H%M%S %Y%m%d", &tm);
+           buff = ppdb_strcat(buff, tmp, NULL, &len);
+       }
+       buff = ppdb_strcat(buff, ",", NULL, &len);
+       
+       tmp = str_pool_getcpy(wpt->shortname, "");
+       while (strchr(tmp, ',') != NULL)
+           *strchr(tmp, ',') = '.';
+       buff = ppdb_strcat(buff, tmp, "", &len);
+       
+       buff = ppdb_strcat(buff, ",", NULL, &len);
+       buff = ppdb_strcat(buff, deficon, "0", &len);
+       buff = ppdb_strcat(buff, ",", NULL, &len);
+
+       tmp = str_pool_getcpy(wpt->description, "");
+       if (strchr(tmp, ',') != NULL )
+       {
+           buff = ppdb_strcat(buff, "\"", NULL, &len);
+           while (strchr(tmp, '"') != NULL)
+               *strchr(tmp, '"') = '\'';
+           buff = ppdb_strcat(buff, tmp,  NULL, &len);
+           buff = ppdb_strcat(buff, "\"", NULL, &len); 
+       }
+       else
+           buff = ppdb_strcat(buff, tmp, "", &len);
+
+       len = strlen(buff) + 1;
+       rec = new_Record(0, 0, ct++, len, (const ubyte *) buff);
+
+       if (rec == NULL) 
+           fatal(MYNAME ": libpdb couldn't create record\n");
+
+       if (pdb_AppendRecord(pdb_out, rec)) 
+           fatal(MYNAME ": libpdb couldn't append record\n");
+           
+       xfree(buff);
+}
+
+/*
+ * track and route write callbacks
+ */
+static void ppdb_track_header(const route_head *rte)
+{
+}
+
+static void ppdb_track_trailer(const route_head *rte)
+{
+}
+
+
+static void ppdb_write(void)
+{
+       ppdb_appdata_t *appinfo = NULL;
+       
+       if (NULL == (pdb_out = new_pdb()))
+           fatal(MYNAME ": new_pdb failed\n");
+       if (dbname)
+           strncpy(pdb_out->name, dbname, PDB_DBNAMELEN);
+           
+       pdb_out->name[PDB_DBNAMELEN-1] = 0;
+       pdb_out->attributes = PDB_ATTR_BACKUP;
+       pdb_out->ctime = pdb_out->mtime = current_time() + 2082844800U;
+       pdb_out->creator = PPDB_MAGIC;
+       pdb_out->version = 3;
+       
+       if (global_opts.objective != wptdata)   /* Waypoint target do not need appinfo block */
+       {
+           appinfo = xmalloc(PPDB_APPINFO_SIZE);
+           memset(appinfo, 0, PPDB_APPINFO_SIZE);
+           
+           pdb_out->appinfo = (void *)appinfo;
+           pdb_out->appinfo_len = PPDB_APPINFO_SIZE;
+       }
+       
+       switch(global_opts.objective)           /* Only one target is possible */
+       {
+           case wptdata:
+               if (dbname == NULL) strncpy(pdb_out->name, "PathAway Waypoints", PDB_DBNAMELEN);
+               pdb_out->type = PPDB_MAGIC_WPT;
+               waypt_disp_all(ppdb_write_wpt);
+               break;
+           case trkdata:
+               if (dbname == NULL) strncpy(pdb_out->name, "PathAway Track", PDB_DBNAMELEN);
+               pdb_out->type = PPDB_MAGIC_TRK;
+               appinfo->dataBaseSubType = 0;
+               track_disp_all(ppdb_track_header, ppdb_track_trailer, ppdb_write_wpt);
+               break;
+           case rtedata:
+               if (dbname == NULL) strncpy(pdb_out->name, "PathAway Route", PDB_DBNAMELEN);
+               pdb_out->type = PPDB_MAGIC_TRK;
+               appinfo->dataBaseSubType = 1;
+               route_disp_all(ppdb_track_header, ppdb_track_trailer, ppdb_write_wpt);
+               break;
+       }
+
+       pdb_Write(pdb_out, fileno(fd_out));
+       
+       if (appinfo != NULL) xfree(appinfo);
+}
+
+
+ff_vecs_t ppdb_vecs = {
+       ff_type_file,
+       FF_CAP_RW_ALL,
+       ppdb_rd_init,   
+       ppdb_wr_init,   
+       ppdb_rd_deinit,
+       ppdb_wr_deinit,
+       ppdb_read,
+       ppdb_write,
+       NULL, 
+       ppdb_args
+};
diff --git a/pcx.c b/pcx.c
index 4b4997b6dbb8571bfec15886e306c283329668d7..fb4f87276feafa6ddeea574d6d5c4a8ba2719b66 100644 (file)
--- a/pcx.c
+++ b/pcx.c
@@ -94,7 +94,7 @@ data_read(void)
                                &symnum);
                        desc[sizeof(desc)-1] = '\0';
                        name[sizeof(name)-1] = '\0';
-                       wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
+                       wpt_tmp = waypt_new();
                        wpt_tmp->altitude = alt;
                        wpt_tmp->shortname = xstrdup(name);
                        wpt_tmp->description = xstrdup(desc);
@@ -194,7 +194,7 @@ gpsutil_disp(const waypoint *wpt)
 
        fprintf(file_out, "W  %-6.6s %c%08.5f %c%011.5f %s %5d %-40.40s %5e  %d\n",
                 global_opts.synthesize_shortnames ?
-                        mkshort(mkshort_handle, wpt->description) : 
+                        mkshort_from_wpt(mkshort_handle, wpt) : 
                        wpt->shortname,
                lat < 0.0 ? 'S' : 'N',
                fabs(lat),
@@ -266,6 +266,7 @@ fprintf(file_out,
 
 ff_vecs_t pcx_vecs = {
        ff_type_file,
+       { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_none },
        rd_init,
        wr_init,
        rd_deinit,
index 9105dfff0a2183dc27d08d0c498af1e4c87f644b..2df410826ae3e885cf97292a01ee331af6c94108 100644 (file)
@@ -35,6 +35,8 @@ static char *latopt = NULL;
 static char *lonopt = NULL;
 static char *exclopt = NULL;
 static char *nosort = NULL;
+static char *maxctarg = NULL;
+static int maxct;
 
 waypoint * home_pos;
 
@@ -64,6 +66,8 @@ arglist_t radius_args[] = {
                NULL, ARGTYPE_BOOL },
        {"nosort", &nosort,    "Inhibit sort by distance to center.",
                NULL, ARGTYPE_BOOL },
+       {"maxcount", &maxctarg,"Output no more than this number of points",
+               NULL, ARGTYPE_INT },
        {0, 0, 0, 0, 0}
 };
 
@@ -221,18 +225,24 @@ position_process_route(const route_head * rh) {
 }
 
 static void 
-position_noop(){
+position_noop_w(const waypoint *w)
+{
 }
 
-void position_process() 
+static void 
+position_noop_t(const route_head *h)
+{
+}
+
+void position_process(void) 
 {
        int i = waypt_count();
        
        if (i)
                position_runqueue(&waypt_head, i, wptdata);
        
-       route_disp_all(position_process_route, position_noop, position_noop);
-       track_disp_all(position_process_route, position_noop, position_noop);
+       route_disp_all(position_process_route, position_noop_t, position_noop_w);
+       track_disp_all(position_process_route, position_noop_t, position_noop_w);
 }
 
 void
@@ -319,8 +329,14 @@ radius_process(void)
         */
        for (i = 0; i < wc; i++) {
                waypoint * wp = comp[i];
-               waypt_add(wp);
+
                xfree(wp->extra_data);
+               wp->extra_data = NULL;
+
+               if (maxctarg && i >= maxct) {
+                       continue;
+               }
+               waypt_add(wp);
        }
 
        xfree(comp);
@@ -341,6 +357,12 @@ radius_init(const char *args) {
                }
        }
 
+       if (maxctarg) {
+               maxct = atoi(maxctarg);
+       } else {
+               maxct = 0;
+       }
+
        home_pos = (waypoint *) xcalloc(sizeof(*home_pos), 1);
 
        if (latopt)
index 9166f830f63764c00e956a8f3feec65dfebae414..89ab8dd9aaa4552f846aaec40e997b7ac4e83984 100644 (file)
--- a/psitrex.c
+++ b/psitrex.c
@@ -208,7 +208,6 @@ static void
 psit_getToken(FILE *psit_file, char *buf, size_t sz, psit_tokenSep_type delimType)
 {
        int c;
-char *buf2 = buf;      /* MRCB debug */
 
        *buf = 0;
 
@@ -285,8 +284,6 @@ psit_waypoint_r(FILE *psit_file, waypoint **wpt)
        int             garmin_icon_num;
 
        waypoint        *thisWaypoint;
-       double  psit_altitude = unknown_alt;
-       double  psit_depth = unknown_alt;
 
        if (strlen(psit_current_token) > 0) {
                thisWaypoint = waypt_new();
@@ -331,10 +328,8 @@ static void
 psit_waypoint_w(FILE *psit_file, const waypoint *wpt)
 {
        int     icon;
-       char *src;
-       const char *ident;
-       int display = 1;
-       int colour = 0;                 /*  (unknown colour) black is 1, white is 16 */
+    const char *ident;
+       char *src = 0;  /* BUGBUG Passed to mkshort */
 
        fprintf(psit_file, "%11.6f,%11.6f,", 
                                                wpt->latitude,
@@ -383,13 +378,10 @@ psit_route_r(FILE *psit_file, route_head **rte)
 
        int             garmin_icon_num;
 
-       time_t  dateTime = 0;
        route_head *rte_head;
        unsigned int rte_count;
 
        waypoint        *thisWaypoint;
-       double  psit_altitude = unknown_alt;
-       double  psit_depth = unknown_alt;
 
        psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
 
@@ -525,8 +517,6 @@ psit_track_r(FILE *psit_file, route_head **trk)
        unsigned int trk_count;
 
        waypoint        *thisWaypoint;
-       double  psit_altitude = unknown_alt;
-       double  psit_depth = unknown_alt;
 
        psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
        if (strlen(psit_current_token) == 0) {
@@ -676,10 +666,6 @@ psit_trackdatapoint_w(FILE *psit_file, const waypoint *wpt)
        time_t  t = wpt->creation_time;
        struct tm *tmTime = gmtime(&t);
 
-       double  psit_altitude = wpt->altitude;
-       double  psit_proximity = unknown_alt;
-       double  psit_depth = unknown_alt;
-
        fprintf(psit_file, "%11.6f,%11.6f,", 
                                                wpt->latitude,
                                                wpt->longitude);
@@ -799,6 +785,7 @@ psit_write(void)
 
 ff_vecs_t psit_vecs = {
        ff_type_file,
+       FF_CAP_RW_ALL,
        psit_rd_init,
        psit_wr_init,
        psit_rd_deinit,
diff --git a/psp.c b/psp.c
index 01fde6645da8dad98034381123923ae2713e135e..b3a04e65097e908b6986c02e3fdbd49c6ff95d4b 100644 (file)
--- a/psp.c
+++ b/psp.c
@@ -158,7 +158,7 @@ buffer_washer(char * buff, int buffer_len)
 
     for (i = 0 ; i < buffer_len - 1; i++) {
        if (buff[i] == '\0') {
-           memcpy(&buff[i], &buff[i+1], buffer_len - i);
+           memmove(&buff[i], &buff[i+1], buffer_len - i);
            buffer_len--;
            buff[buffer_len] = '\0';
        }
@@ -215,7 +215,7 @@ psp_read(void)
        pincount = le_read16(&buff[12]);
 
        while (pincount--) {
-           wpt_tmp = xcalloc(sizeof(*wpt_tmp),1);
+           wpt_tmp = waypt_new();
 
             wpt_tmp->altitude = unknown_alt;
             
@@ -327,7 +327,7 @@ psp_waypt_pr(const waypoint *wpt)
         if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) {
             if (wpt->description) {
                 if (global_opts.synthesize_shortnames)
-                    shortname = mkshort(mkshort_handle, wpt->description);
+                    shortname = mkshort_from_wpt(mkshort_handle, wpt);
                 else
                     shortname = xstrdup(wpt->description);
             } else {
@@ -459,6 +459,7 @@ psp_write(void)
 
 ff_vecs_t psp_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        psp_rd_init,
        psp_wr_init,
        psp_rd_deinit,
diff --git a/queue.h b/queue.h
index 2cbb72748eb574a3eb125392b10659b4c3759332..e042e235e2de6580847652d86845e35a3a58ce5f 100644 (file)
--- a/queue.h
+++ b/queue.h
@@ -33,10 +33,15 @@ queue * dequeue(queue *element);
 #define QUEUE_LAST(head) (head)->prev
 #define QUEUE_EMPTY (head)->next == head
 #define QUEUE_MOVE(newhead,oldhead) \
-       (newhead)->next = (oldhead)->next; \
-       (newhead)->prev = (oldhead)->prev; \
-       (newhead)->next->prev = (newhead); \
-       (newhead)->prev->next = (newhead); \
+        if ( (oldhead)->next == (oldhead) ) {\
+               (newhead)->next = (newhead)->prev = (newhead); \
+       } \
+       else { \
+               (newhead)->next = (oldhead)->next; \
+               (newhead)->prev = (oldhead)->prev; \
+               (newhead)->next->prev = (newhead); \
+               (newhead)->prev->next = (newhead); \
+       } \
        (oldhead)->next = (oldhead)->prev = (oldhead)
 
 #define ENQUEUE_TAIL(listhead, element) \
index a5274f801b5de14785c3fa34d666d4d158625c8c..e71eda8921da3dd3af43ab580959a5a9e378d565 100644 (file)
@@ -173,9 +173,9 @@ quovadis_writewpt(waypoint *wpt)
 
     rec = (struct record *) xcalloc(sizeof(*rec),1);
 
-    be_write32(&rec->longitude, (wpt->longitude +
-                                180.0) * 1000000.0);
-    be_write32(&rec->latitude, (90.0 - wpt->latitude) * 1000000.0);
+    be_write32(&rec->longitude, (unsigned int) ((wpt->longitude +
+                                180.0) * 1000000.0));
+    be_write32(&rec->latitude, (unsigned int) ((90.0 - wpt->latitude) * 1000000.0));
     if ( wpt->shortname ) {
        strncpy(rec->name, wpt->shortname, 32 );
        rec->name[31] = '\0';
@@ -265,8 +265,8 @@ data_write(void)
 
        if (rec_index != 0) {
            struct pdb_record* pdb_rec;
-           pdb_rec = new_Record(0, 0, ct++, rec_index *
-                                sizeof(struct record), current_rec);
+           pdb_rec = new_Record(0, 0, ct++, (uword) (rec_index *
+                                sizeof(struct record)), current_rec);
        
            if (pdb_rec == NULL) {
                fatal(MYNAME ": libpdb couldn't create record\n");
@@ -285,6 +285,7 @@ data_write(void)
 
 ff_vecs_t quovadis_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
index 458090147496009e8ce44a14fc50721399e49fd2..f2397b966b1c3f5caaf2453f51fcda3cffe19550 100644 (file)
                <LastModified>0</LastModified>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEdward Island\1flegnum0\1fusrmrkEdward Island\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEdward Island\1flegnum0\1fusrmrkEdward Island\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-20.226667</Latitude>
                        <Longitude>149.205000</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMScawfell Island\1flegnum1\1fusrmrkScawfell Island\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMScawfell Island\1flegnum1\1fusrmrkScawfell Island\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-20.850001</Latitude>
-                       <Longitude>149.641668</Longitude>
+                       <Latitude>-20.850000</Latitude>
+                       <Longitude>149.641667</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMiddle Island\1flegnum2\1fusrmrkMiddle Island\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMiddle Island\1flegnum2\1fusrmrkMiddle Island\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-21.680097</Latitude>
                        <Longitude>150.176053</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMClara Group\1flegnum3\1fusrmrkClara Group\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMClara Group\1flegnum3\1fusrmrkClara Group\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-22.318424</Latitude>
-                       <Longitude>150.747717</Longitude>
+                       <Longitude>150.747716</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMCape Capricorn\1flegnum4\1fusrmrkCape Capricorn\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMCape Capricorn\1flegnum4\1fusrmrkCape Capricorn\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-23.448418</Latitude>
-                       <Longitude>151.322717</Longitude>
+                       <Latitude>-23.448417</Latitude>
+                       <Longitude>151.322716</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGladstone FWB\1flegnum5\1fusrmrkGladstone FWB\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGladstone FWB\1flegnum5\1fusrmrkGladstone FWB\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-23.890915</Latitude>
-                       <Longitude>151.516051</Longitude>
+                       <Latitude>-23.890914</Latitude>
+                       <Longitude>151.516050</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHigh Peak\1flegnum6\1fusrmrkHigh Peak\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHigh Peak\1flegnum6\1fusrmrkHigh Peak\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-21.951660</Latitude>
-                       <Longitude>150.754997</Longitude>
+                       <Latitude>-21.951659</Latitude>
+                       <Longitude>150.754996</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPenrith Island\1flegnum7\1fusrmrkPenrith Island\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPenrith Island\1flegnum7\1fusrmrkPenrith Island\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-20.988435</Latitude>
-                       <Longitude>149.929386</Longitude>
+                       <Latitude>-20.988434</Latitude>
+                       <Longitude>149.929385</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPinnacle Point\1flegnum8\1fusrmrkPinnacle Point\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPinnacle Point\1flegnum8\1fusrmrkPinnacle Point\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-20.081094</Latitude>
-                       <Longitude>149.064391</Longitude>
+                       <Latitude>-20.081093</Latitude>
+                       <Longitude>149.064390</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMTink Shoal\1flegnum9\1fusrmrkTink Shoal\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMTink Shoal\1flegnum9\1fusrmrkTink Shoal\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-19.375083</Latitude>
-                       <Longitude>147.819368</Longitude>
+                       <Longitude>147.819367</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPelorus\1flegnum10\1fusrmrkPelorus\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPelorus\1flegnum10\1fusrmrkPelorus\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-18.433464</Latitude>
-                       <Longitude>146.549414</Longitude>
+                       <Longitude>146.549413</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEva Island\1flegnum11\1fusrmrkEva Island\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEva Island\1flegnum11\1fusrmrkEva Island\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-18.213466</Latitude>
-                       <Longitude>146.409415</Longitude>
+                       <Longitude>146.409414</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMLittle Fitzroy Island\1flegnum12\1fusrmrkLittle Fitzroy Island\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMLittle Fitzroy Island\1flegnum12\1fusrmrkLittle Fitzroy Island\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-16.913473</Latitude>
-                       <Longitude>146.059411</Longitude>
+                       <Longitude>146.059410</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMCairns FWB\1flegnum13\1fusrmrkCairns FWB\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMCairns FWB\1flegnum13\1fusrmrkCairns FWB\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-16.731976</Latitude>
+                       <Latitude>-16.731975</Latitude>
                        <Longitude>145.889412</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMLow Isles\1flegnum14\1fusrmrkLow Isles\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMLow Isles\1flegnum14\1fusrmrkLow Isles\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-16.465145</Latitude>
+                       <Latitude>-16.465144</Latitude>
                        <Longitude>145.637746</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPickersgill Reef\1flegnum15\1fusrmrkPickersgill Reef\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPickersgill Reef\1flegnum15\1fusrmrkPickersgill Reef\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-15.921815</Latitude>
+                       <Latitude>-15.921814</Latitude>
                        <Longitude>145.481079</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGubbins\1flegnum16\1fusrmrkGubbins\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGubbins\1flegnum16\1fusrmrkGubbins\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-15.708467</Latitude>
-                       <Longitude>145.382747</Longitude>
+                       <Latitude>-15.708466</Latitude>
+                       <Longitude>145.382746</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMThree Isles\1flegnum17\1fusrmrkThree Isles\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMThree Isles\1flegnum17\1fusrmrkThree Isles\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-15.110153</Latitude>
+                       <Latitude>-15.110152</Latitude>
                        <Longitude>145.402742</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPalfrey\1flegnum18\1fusrmrkPalfrey\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPalfrey\1flegnum18\1fusrmrkPalfrey\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-14.673488</Latitude>
-                       <Longitude>145.417741</Longitude>
+                       <Longitude>145.417740</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMNymph Island\1flegnum19\1fusrmrkNymph Island\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMNymph Island\1flegnum19\1fusrmrkNymph Island\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-14.626822</Latitude>
-                       <Longitude>145.251076</Longitude>
+                       <Longitude>145.251075</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMCoquet\1flegnum20\1fusrmrkCoquet\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMCoquet\1flegnum20\1fusrmrkCoquet\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-14.546824</Latitude>
-                       <Longitude>145.061078</Longitude>
+                       <Latitude>-14.546823</Latitude>
+                       <Longitude>145.061077</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHowick\1flegnum21\1fusrmrkHowick\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHowick\1flegnum21\1fusrmrkHowick\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-14.483492</Latitude>
-                       <Longitude>144.979412</Longitude>
+                       <Latitude>-14.483491</Latitude>
+                       <Longitude>144.979411</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMegaera\1flegnum22\1fusrmrkMegaera\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMegaera\1flegnum22\1fusrmrkMegaera\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-14.483492</Latitude>
-                       <Longitude>144.932746</Longitude>
+                       <Latitude>-14.483491</Latitude>
+                       <Longitude>144.932745</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWatson\1flegnum23\1fusrmrkWatson\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWatson\1flegnum23\1fusrmrkWatson\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-14.451826</Latitude>
-                       <Longitude>144.902746</Longitude>
+                       <Latitude>-14.451825</Latitude>
+                       <Longitude>144.902745</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMBarrow\1flegnum24\1fusrmrkBarrow\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMBarrow\1flegnum24\1fusrmrkBarrow\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-14.361826</Latitude>
-                       <Longitude>144.686082</Longitude>
+                       <Longitude>144.686081</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMRocky Point\1flegnum25\1fusrmrkRocky Point\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMRocky Point\1flegnum25\1fusrmrkRocky Point\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-14.195161</Latitude>
                        <Longitude>144.604414</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPipon\1flegnum26\1fusrmrkPipon\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPipon\1flegnum26\1fusrmrkPipon\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-14.138495</Latitude>
                        <Longitude>144.511082</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMKing Island\1flegnum27\1fusrmrkKing Island\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMKing Island\1flegnum27\1fusrmrkKing Island\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-14.060164</Latitude>
-                       <Longitude>144.331084</Longitude>
+                       <Latitude>-14.060163</Latitude>
+                       <Longitude>144.331083</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMClack Island\1flegnum28\1fusrmrkClack Island\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMClack Island\1flegnum28\1fusrmrkClack Island\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-14.101829</Latitude>
                        <Longitude>144.244418</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWharton Reef\1flegnum29\1fusrmrkWharton Reef\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWharton Reef\1flegnum29\1fusrmrkWharton Reef\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-14.101831</Latitude>
-                       <Longitude>143.977755</Longitude>
+                       <Longitude>143.977754</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEden\1flegnum30\1fusrmrkEden\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEden\1flegnum30\1fusrmrkEden\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-14.065165</Latitude>
-                       <Longitude>143.917756</Longitude>
+                       <Latitude>-14.065164</Latitude>
+                       <Longitude>143.917755</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMStainer Reef\1flegnum31\1fusrmrkStainer Reef\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMStainer Reef\1flegnum31\1fusrmrkStainer Reef\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-13.981832</Latitude>
                        <Longitude>143.834422</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPelican\1flegnum32\1fusrmrkPelican\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPelican\1flegnum32\1fusrmrkPelican\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-13.915167</Latitude>
-                       <Longitude>143.812756</Longitude>
+                       <Latitude>-13.915166</Latitude>
+                       <Longitude>143.812755</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMagpie\1flegnum33\1fusrmrkMagpie\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMagpie\1flegnum33\1fusrmrkMagpie\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-13.815167</Latitude>
                        <Longitude>143.734423</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMFife\1flegnum34\1fusrmrkFife\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMFife\1flegnum34\1fusrmrkFife\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-13.656835</Latitude>
+                       <Latitude>-13.656834</Latitude>
                        <Longitude>143.704422</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHeath Reef\1flegnum35\1fusrmrkHeath Reef\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHeath Reef\1flegnum35\1fusrmrkHeath Reef\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-13.475170</Latitude>
-                       <Longitude>143.671089</Longitude>
+                       <Latitude>-13.475169</Latitude>
+                       <Longitude>143.671088</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMBow Reef\1flegnum36\1fusrmrkBow Reef\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMBow Reef\1flegnum36\1fusrmrkBow Reef\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-13.341836</Latitude>
-                       <Longitude>143.671089</Longitude>
+                       <Longitude>143.671088</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMOsborne\1flegnum37\1fusrmrkOsborne\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMOsborne\1flegnum37\1fusrmrkOsborne\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-13.096838</Latitude>
                        <Longitude>143.611087</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMChapman\1flegnum38\1fusrmrkChapman\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMChapman\1flegnum38\1fusrmrkChapman\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-12.886839</Latitude>
                        <Longitude>143.594420</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWye Reef\1flegnum39\1fusrmrkWye Reef\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWye Reef\1flegnum39\1fusrmrkWye Reef\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-12.818506</Latitude>
                        <Longitude>143.586087</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEel Reef\1flegnum40\1fusrmrkEel Reef\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEel Reef\1flegnum40\1fusrmrkEel Reef\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-12.415159</Latitude>
                        <Longitude>143.362754</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPiper\1flegnum41\1fusrmrkPiper\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMPiper\1flegnum41\1fusrmrkPiper\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-12.236844</Latitude>
                        <Longitude>143.247755</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMoody\1flegnum42\1fusrmrkMoody\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMoody\1flegnum42\1fusrmrkMoody\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-12.085178</Latitude>
                        <Longitude>143.239421</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMClerke\1flegnum43\1fusrmrkClerke\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMClerke\1flegnum43\1fusrmrkClerke\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-11.963513</Latitude>
-                       <Longitude>143.317754</Longitude>
+                       <Latitude>-11.963512</Latitude>
+                       <Longitude>143.317753</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHannibal\1flegnum44\1fusrmrkHannibal\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHannibal\1flegnum44\1fusrmrkHannibal\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-11.586850</Latitude>
-                       <Longitude>142.981089</Longitude>
+                       <Latitude>-11.586849</Latitude>
+                       <Longitude>142.981088</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHalfway\1flegnum45\1fusrmrkHalfway\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHalfway\1flegnum45\1fusrmrkHalfway\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-11.378517</Latitude>
                        <Longitude>142.986088</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMCairncross\1flegnum46\1fusrmrkCairncross\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMCairncross\1flegnum46\1fusrmrkCairncross\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-11.231851</Latitude>
-                       <Longitude>142.954422</Longitude>
+                       <Longitude>142.954421</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWyborn\1flegnum47\1fusrmrkWyborn\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWyborn\1flegnum47\1fusrmrkWyborn\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-10.806855</Latitude>
                        <Longitude>142.804421</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMAlbany Rock\1flegnum48\1fusrmrkAlbany Rock\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMAlbany Rock\1flegnum48\1fusrmrkAlbany Rock\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-10.741856</Latitude>
+                       <Latitude>-10.741855</Latitude>
                        <Longitude>142.676089</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMAlpha Rock\1flegnum49\1fusrmrkAlpha Rock\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMAlpha Rock\1flegnum49\1fusrmrkAlpha Rock\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-10.601857</Latitude>
                        <Longitude>142.552756</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHerald Patches\1flegnum50\1fusrmrkHerald Patches\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHerald Patches\1flegnum50\1fusrmrkHerald Patches\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-10.501859</Latitude>
-                       <Longitude>142.377759</Longitude>
+                       <Latitude>-10.501858</Latitude>
+                       <Longitude>142.377758</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEast Strait Leads\1flegnum51\1fusrmrkEast Strait Leads\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMEast Strait Leads\1flegnum51\1fusrmrkEast Strait Leads\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-10.480192</Latitude>
-                       <Longitude>142.334426</Longitude>
+                       <Longitude>142.334425</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMShadwell Point\1flegnum52\1fusrmrkShadwell Point\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMShadwell Point\1flegnum52\1fusrmrkShadwell Point\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-10.495193</Latitude>
-                       <Longitude>142.282760</Longitude>
+                       <Latitude>-10.495192</Latitude>
+                       <Longitude>142.282759</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMNardana\1flegnum53\1fusrmrkNardana\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMNardana\1flegnum53\1fusrmrkNardana\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-10.508525</Latitude>
-                       <Longitude>142.251094</Longitude>
+                       <Longitude>142.251093</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHammond\1flegnum54\1fusrmrkHammond\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHammond\1flegnum54\1fusrmrkHammond\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-10.510193</Latitude>
-                       <Longitude>142.202761</Longitude>
+                       <Latitude>-10.510192</Latitude>
+                       <Longitude>142.202760</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHarrison\1flegnum55\1fusrmrkHarrison\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMHarrison\1flegnum55\1fusrmrkHarrison\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-10.561860</Latitude>
+                       <Latitude>-10.561859</Latitude>
                        <Longitude>142.126094</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMB1\1flegnum56\1fusrmrkB1\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMB1\1flegnum56\1fusrmrkB1\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-10.568518</Latitude>
-                       <Longitude>141.909434</Longitude>
+                       <Latitude>-10.568517</Latitude>
+                       <Longitude>141.909433</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMRed Banks\1flegnum57\1fusrmrkRed Banks\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMRed Banks\1flegnum57\1fusrmrkRed Banks\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-10.829183</Latitude>
-                       <Longitude>141.659174</Longitude>
+                       <Latitude>-10.829182</Latitude>
+                       <Longitude>141.659173</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMDuyfken Pt\1flegnum58\1fusrmrkDuyfken Pt\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMDuyfken Pt\1flegnum58\1fusrmrkDuyfken Pt\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-12.568516</Latitude>
                        <Longitude>141.501109</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWeipa Leads\1flegnum59\1fusrmrkWeipa Leads\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWeipa Leads\1flegnum59\1fusrmrkWeipa Leads\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-12.705000</Latitude>
                        <Longitude>141.661667</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWeipa FWB\1flegnum60\1fusrmrkWeipa FWB\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMWeipa FWB\1flegnum60\1fusrmrkWeipa FWB\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-12.700000</Latitude>
                        <Longitude>141.688333</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGannet\1flegnum61\1fusrmrkGannet\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGannet\1flegnum61\1fusrmrkGannet\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-10.590757</Latitude>
                        <Longitude>141.875120</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMB2\1flegnum62\1fusrmrkB2\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMB2\1flegnum62\1fusrmrkB2\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-10.575158</Latitude>
                        <Longitude>141.891066</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMid Decap\1flegnum63\1fusrmrkMid Decap\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMMid Decap\1flegnum63\1fusrmrkMid Decap\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-14.965864</Latitude>
                        <Longitude>145.407427</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMTurtle\1flegnum64\1fusrmrkTurtle\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMTurtle\1flegnum64\1fusrmrkTurtle\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>-14.632647</Latitude>
-                       <Longitude>145.189251</Longitude>
+                       <Longitude>145.189250</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMNewton\1flegnum65\1fusrmrkNewton\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMNewton\1flegnum65\1fusrmrkNewton\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
-                       <Latitude>-14.517176</Latitude>
-                       <Longitude>144.911975</Longitude>
+                       <Latitude>-14.517175</Latitude>
+                       <Longitude>144.911974</Longitude>
                </Object>
        </Route>
 </Export>
diff --git a/reference/an1-an1.ref b/reference/an1-an1.ref
new file mode 100644 (file)
index 0000000..17df313
Binary files /dev/null and b/reference/an1-an1.ref differ
diff --git a/reference/an1-in.ref b/reference/an1-in.ref
new file mode 100644 (file)
index 0000000..a374b99
--- /dev/null
@@ -0,0 +1,26 @@
+41.11111, -85.16351, 
+41.11048, -85.16341, 
+41.10986, -85.16348, 
+41.10908, -85.16357, 
+41.11138, -85.16216, 
+41.11058, -85.16223, 
+41.10990, -85.16239, 
+41.10923, -85.16255, 
+41.11138, -85.16130, 
+41.11068, -85.16127, 
+41.11000, -85.16139, 
+41.10920, -85.16155, 
+41.11142, -85.16002, 
+41.11075, -85.16030, 
+41.11005, -85.16050, 
+41.10964, -85.16062, 
+41.10824, -85.16373, 
+41.10821, -85.16300, 
+41.10817, -85.16216, 
+41.10846, -85.16123, 
+41.10768, -85.16409, 
+41.10756, -85.16300, 
+41.10768, -85.16210, 
+41.10778, -85.16123, 
+41.10684, -85.16383, 
+41.10681, -85.16287, 
diff --git a/reference/an1-line-out.ref b/reference/an1-line-out.ref
new file mode 100644 (file)
index 0000000..9518280
Binary files /dev/null and b/reference/an1-line-out.ref differ
diff --git a/reference/an1-out.ref b/reference/an1-out.ref
new file mode 100644 (file)
index 0000000..bcaff77
Binary files /dev/null and b/reference/an1-out.ref differ
diff --git a/reference/coastexp.nob b/reference/coastexp.nob
new file mode 100644 (file)
index 0000000..8991756
--- /dev/null
@@ -0,0 +1,370 @@
+<?xml version="1.0"?>\r
+<NavObjectCollection created="20041105T170900Z">\r
+       <Name>Navigation Objects</Name>\r
+       <Visible>true</Visible>\r
+       <ViewSettings created="20041105T171914Z">\r
+               <Position>34.867273 N 120.589158 W</Position>\r
+               <Scale>98208.414698</Scale>\r
+               <Quilting>true</Quilting>\r
+               <ShowVectorCharts>true</ShowVectorCharts>\r
+       </ViewSettings>\r
+       <Route created="20041105T170906Z" id="{58384b15-2ed7-4cee-a827-368917b2c743}">\r
+               <Marks>\r
+                       {76e5356a-d5fc-4437-8649-026416c2b185}\r
+                       {d5dbd16f-eeba-4f61-b38f-582b584e5db3}\r
+                       {9816402a-51a6-4fd5-8c08-b680d23d7911}\r
+                       {427ed2ff-bdbb-4d77-b859-1f1eff10c961}\r
+                       {0ead9569-64f0-4fb8-9545-4fa3191bbab0}\r
+                       {fbe5b26d-b111-4208-ac70-f22b169d9c3e}\r
+                       {68cfe23d-2ebf-4075-9726-f743659c7df5}\r
+                       {50740d73-e743-4197-a6a0-29ad3114107a}\r
+                       {26ae0ba0-a73e-4600-b51a-546d7099c809}\r
+                       {b7266cd5-817b-4674-862e-490230a2f925}\r
+               </Marks>\r
+               <RouteLeg created="20041105T170909Z" id="{0699ae10-6257-4d1d-b6e7-37fe694dac26}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <RouteLeg created="20041105T170910Z" id="{03dd3451-7040-4e6f-aeb7-6ed6b87612b8}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <RouteLeg created="20041105T170913Z" id="{87a407a6-11a5-4b5e-a55e-8484e47da0ee}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <RouteLeg created="20041105T170916Z" id="{421115ff-a94a-48f4-acd1-36cf3387e79b}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <RouteLeg created="20041105T170920Z" id="{2c587ebf-4e0c-43ad-ae89-4da44819b093}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <RouteLeg created="20041105T170926Z" id="{a653ca32-e125-4377-8b86-b254f414ca86}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <RouteLeg created="20041105T170927Z" id="{4d32d150-2a89-46d6-993f-1fe54a8f62dc}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <RouteLeg created="20041105T211624Z" id="{3bf50ccf-2d8a-46dc-9574-3fe7ca55f8fc}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <RouteLeg created="20041105T170929Z" id="{eb96f93d-6367-4ccf-9850-d84bb5227022}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <RouteLeg created="20041105T170930Z" id="{74f699b8-8b59-4d9a-9656-11877a0a0dcc}">\r
+                       <PlannedSpeed>5.0 kn</PlannedSpeed>\r
+               </RouteLeg>\r
+               <DisplayLegRangeBearing>true</DisplayLegRangeBearing>\r
+               <TotalLength>39.06 NM</TotalLength>\r
+               <StartTime>20050516T070000</StartTime>\r
+               <StartAt>first-waypoint</StartAt>\r
+               <Name>Into The Bay</Name>\r
+       </Route>\r
+       <Mark created="20041105T170909Z" id="{76e5356a-d5fc-4437-8649-026416c2b185}">\r
+               <Position>37.763290 N 122.282580 W</Position>\r
+               <Icon>Home</Icon>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-51,-21</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SFBALBAY</Name>\r
+       </Mark>\r
+       <Mark created="20041105T170910Z" id="{d5dbd16f-eeba-4f61-b38f-582b584e5db3}">\r
+               <Position>37.751613 N 122.339028 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-58,4</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SFBAY001</Name>\r
+       </Mark>\r
+       <Mark created="20041105T170913Z" id="{9816402a-51a6-4fd5-8c08-b680d23d7911}">\r
+               <Position>37.817420 N 122.394305 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-9,-19</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SFBAY002</Name>\r
+       </Mark>\r
+       <Mark created="20041105T170916Z" id="{427ed2ff-bdbb-4d77-b859-1f1eff10c961}">\r
+               <Position>37.819339 N 122.478302 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-53,-21</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SFGGBRDG</Name>\r
+       </Mark>\r
+       <Mark created="20041105T170920Z" id="{0ead9569-64f0-4fb8-9545-4fa3191bbab0}">\r
+               <Position>37.773033 N 122.605838 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-92,-13</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SFCHNL01</Name>\r
+       </Mark>\r
+       <Mark created="20041105T170926Z" id="{fbe5b26d-b111-4208-ac70-f22b169d9c3e}">\r
+               <Position>37.518860 N 122.529914 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-98,-4</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>HMCOLREF</Name>\r
+       </Mark>\r
+       <Mark created="20041105T170927Z" id="{68cfe23d-2ebf-4075-9726-f743659c7df5}">\r
+               <Position>37.482348 N 122.507704 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-77,1</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>HMPILL01</Name>\r
+       </Mark>\r
+       <Mark created="20041105T170929Z" id="{26ae0ba0-a73e-4600-b51a-546d7099c809}">\r
+               <Position>37.476448 N 122.475800 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>13,-1</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>HMPILL02</Name>\r
+       </Mark>\r
+       <Mark created="20041105T170930Z" id="{b7266cd5-817b-4674-862e-490230a2f925}">\r
+               <Position>37.495102 N 122.483927 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-91,-4</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>HMPILL03</Name>\r
+       </Mark>\r
+       <Mark created="20041105T211300Z" id="{5bf0873d-5c50-4ad4-8c36-e8d90b068908}">\r
+               <Position>37.229349 N 122.441589 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-95,-4</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PESCDR01</Name>\r
+       </Mark>\r
+       <Mark created="20041105T211324Z" id="{625fb518-f83b-4e24-add2-852544d6fc52}">\r
+               <Position>37.183397 N 122.411904 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-90,-2</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PIGEON01</Name>\r
+       </Mark>\r
+       <Mark created="20041105T211341Z" id="{1677d889-5a9e-463e-b398-03da7165d31d}">\r
+               <Position>37.090736 N 122.348775 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-89,0</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>ANONUV01</Name>\r
+       </Mark>\r
+       <Mark created="20041105T211409Z" id="{aac62a78-9a10-4c98-b057-3bd05cb667c2}">\r
+               <Position>36.929502 N 122.113725 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-51,4</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SCRUZ01</Name>\r
+       </Mark>\r
+       <Mark created="20041105T211416Z" id="{2972124d-66f4-48a7-932d-2100eb3f5f6d}">\r
+               <Position>36.934235 N 122.022130 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>22,-8</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SCRUZ02</Name>\r
+       </Mark>\r
+       <Mark created="20041105T211420Z" id="{aabdee59-c849-4eaf-8005-b1e814650244}">\r
+               <Position>36.960666 N 122.024734 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>22,-9</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SCRUZENT</Name>\r
+       </Mark>\r
+       <Mark created="20041105T211624Z" id="{50740d73-e743-4197-a6a0-29ad3114107a}">\r
+               <Position>37.475062 N 122.488531 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-44,5</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>HMPILLPT</Name>\r
+       </Mark>\r
+       <Mark created="20041105T212422Z" id="{83540001-9f5d-4cb5-8218-51bfaeb7b3e8}">\r
+               <Position>36.581344 N 121.995411 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-95,-7</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>CYPRSSPT</Name>\r
+       </Mark>\r
+       <Mark created="20041105T212438Z" id="{311a8303-dc05-497d-aaa6-d4cba53e3464}">\r
+               <Position>36.301110 N 121.919097 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-67,-3</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PTSUR</Name>\r
+       </Mark>\r
+       <Mark created="20041105T212515Z" id="{2a7de189-ea1b-46d5-a168-d9ada708f50b}">\r
+               <Position>36.238177 N 121.855209 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-72,3</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>COOPERPT</Name>\r
+       </Mark>\r
+       <Mark created="20041105T212526Z" id="{3d6f3fe8-bc77-4d0b-9b4d-7fe1e41c5691}">\r
+               <Position>36.225175 N 121.801314 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-91,-8</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PFEIFENT</Name>\r
+       </Mark>\r
+       <Mark created="20041105T212531Z" id="{12481c1c-7f84-48d7-a7ad-ac613a036cea}">\r
+               <Position>36.230449 N 121.797444 W</Position>\r
+               <Icon>Anchor</Icon>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-85,-14</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PFEIFANC</Name>\r
+       </Mark>\r
+       <Mark created="20041105T212826Z" id="{d04c1156-4ca6-4b79-8177-929796c0c330}">\r
+               <Position>35.879801 N 121.498947 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>10,-15</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SANMRT01</Name>\r
+       </Mark>\r
+       <Mark created="20041105T212833Z" id="{724553f0-6d4a-48c7-9813-c61d1b9e64f3}">\r
+               <Position>35.652801 N 121.308485 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-75,2</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PDRSBLNC</Name>\r
+       </Mark>\r
+       <Mark created="20041105T212850Z" id="{3f52e80e-0c8d-4e8f-ba57-0b99ff5a1b41}">\r
+               <Position>35.623297 N 121.185920 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-102,-6</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SNSMNENT</Name>\r
+       </Mark>\r
+       <Mark created="20041105T212853Z" id="{409cc119-ed3f-4d02-8ccc-c738dcbdd96b}">\r
+               <Position>35.640478 N 121.183772 W</Position>\r
+               <Icon>Anchor</Icon>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-105,-9</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SNSMNANC</Name>\r
+       </Mark>\r
+       <Mark created="20041105T213618Z" id="{6d0a144a-6ce0-466c-9af4-478bc375580c}">\r
+               <Position>35.572353 N 121.152797 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-80,-1</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>CAMBRIA</Name>\r
+       </Mark>\r
+       <Mark created="20041105T213626Z" id="{3d9062c5-e059-457d-859c-549dea0c101f}">\r
+               <Position>35.449214 N 121.020825 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>14,-14</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PTESTERO</Name>\r
+       </Mark>\r
+       <Mark created="20041105T213635Z" id="{8f66e2de-fa62-43d5-af69-44724867429b}">\r
+               <Position>35.216602 N 120.928391 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-96,-3</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PTBUCHON</Name>\r
+       </Mark>\r
+       <Mark created="20041105T213642Z" id="{15b56103-0d91-446a-9e0f-0d5817581f9b}">\r
+               <Position>34.883361 N 120.684631 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-57,3</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PTSAL01</Name>\r
+       </Mark>\r
+       <Mark created="20041105T213647Z" id="{361b3cd3-1e77-4867-b956-d01b152ed22d}">\r
+               <Position>34.884641 N 120.652026 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-96,-8</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PTSALENT</Name>\r
+               <Description>A description of the Point Sal Entrance mark</Description>\r
+       </Mark>\r
+       <Mark created="20041105T213704Z" id="{4d6b54b8-b3e5-42f0-ab33-f90b60752bcd}">\r
+               <Position>34.896555 N 120.649124 W</Position>\r
+               <Icon>Anchor</Icon>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-96,-10</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PTSALANC</Name>\r
+       </Mark>\r
+       <Mark created="20041105T213949Z" id="{d5bfc894-670e-47c7-9a0f-74e406fdf3ca}">\r
+               <Position>34.758180 N 120.642516 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>22,-8</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PURSMAPT</Name>\r
+       </Mark>\r
+       <Mark created="20041105T213954Z" id="{682a9c6d-a632-4e8b-acd8-42d156a2fe3e}">\r
+               <Position>34.572579 N 120.663636 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-97,-7</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>PTARGLLO</Name>\r
+       </Mark>\r
+       <Mark created="20041105T214005Z" id="{8787e521-19cb-400a-9efc-1b8863b70132}">\r
+               <Position>34.113844 N 120.492630 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>20,-11</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SANMGL01</Name>\r
+       </Mark>\r
+       <Mark created="20041105T214044Z" id="{33aa93e4-da08-42c6-a42c-49cf71eff499}">\r
+               <Position>34.029483 N 120.471409 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-88,0</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SANMGL02</Name>\r
+       </Mark>\r
+       <Mark created="20041105T214048Z" id="{61fe867b-1b99-49b1-8188-adda5069cccf}">\r
+               <Position>34.019184 N 120.444197 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-32,5</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>SANMGL03</Name>\r
+       </Mark>\r
+       <Mark created="20041105T214057Z" id="{b3dc7ee2-ffe1-458d-be60-b3a92f089ae4}">\r
+               <Position>34.023478 N 120.438209 W</Position>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>19,-4</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>ADCOVENT</Name>\r
+       </Mark>\r
+       <Mark created="20041105T214059Z" id="{d2e24f39-796a-4853-8d3a-32106be5e2b7}">\r
+               <Position>34.028615 N 120.439696 W</Position>\r
+               <Icon>Anchor</Icon>\r
+               <ArrivalCircleRadius>0.05 NM</ArrivalCircleRadius>\r
+               <RangeCircleRadius>0 NM</RangeCircleRadius>\r
+               <NameOffset>-102,-5</NameOffset>\r
+               <DescriptionOffset>0,24</DescriptionOffset>\r
+               <Name>ADCOVANC</Name>\r
+       </Mark>\r
+</NavObjectCollection>\r
diff --git a/reference/coastexp.ref b/reference/coastexp.ref
new file mode 100644 (file)
index 0000000..98df894
--- /dev/null
@@ -0,0 +1,221 @@
+<?xml version="1.0"?>
+<gpx
+ version="1.0"
+creator="GPSBabel - http://www.gpsbabel.org"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.topografix.com/GPX/1/0"
+xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+<time>1970-01-01T00:00:00Z</time>
+<bounds minlat="34.019184000" minlon ="-122.441589000" maxlat="37.229349000" maxlon="-120.438209000" />
+<wpt lat="37.229349000" lon="-122.441589000">
+<time>2004-11-05T21:13:00Z</time>
+  <name>PESCDR01</name>
+  <cmt>PESCDR01</cmt>
+  <desc>PESCDR01</desc>
+</wpt>
+<wpt lat="37.183397000" lon="-122.411904000">
+<time>2004-11-05T21:13:24Z</time>
+  <name>PIGEON01</name>
+  <cmt>PIGEON01</cmt>
+  <desc>PIGEON01</desc>
+</wpt>
+<wpt lat="37.090736000" lon="-122.348775000">
+<time>2004-11-05T21:13:41Z</time>
+  <name>ANONUV01</name>
+  <cmt>ANONUV01</cmt>
+  <desc>ANONUV01</desc>
+</wpt>
+<wpt lat="36.929502000" lon="-122.113725000">
+<time>2004-11-05T21:14:09Z</time>
+  <name>SCRUZ01</name>
+  <cmt>SCRUZ01</cmt>
+  <desc>SCRUZ01</desc>
+</wpt>
+<wpt lat="36.934235000" lon="-122.022130000">
+<time>2004-11-05T21:14:16Z</time>
+  <name>SCRUZ02</name>
+  <cmt>SCRUZ02</cmt>
+  <desc>SCRUZ02</desc>
+</wpt>
+<wpt lat="36.960666000" lon="-122.024734000">
+<time>2004-11-05T21:14:20Z</time>
+  <name>SCRUZENT</name>
+  <cmt>SCRUZENT</cmt>
+  <desc>SCRUZENT</desc>
+</wpt>
+<wpt lat="36.581344000" lon="-121.995411000">
+<time>2004-11-05T21:24:22Z</time>
+  <name>CYPRSSPT</name>
+  <cmt>CYPRSSPT</cmt>
+  <desc>CYPRSSPT</desc>
+</wpt>
+<wpt lat="36.301110000" lon="-121.919097000">
+<time>2004-11-05T21:24:38Z</time>
+  <name>PTSUR</name>
+  <cmt>PTSUR</cmt>
+  <desc>PTSUR</desc>
+</wpt>
+<wpt lat="36.238177000" lon="-121.855209000">
+<time>2004-11-05T21:25:15Z</time>
+  <name>COOPERPT</name>
+  <cmt>COOPERPT</cmt>
+  <desc>COOPERPT</desc>
+</wpt>
+<wpt lat="36.225175000" lon="-121.801314000">
+<time>2004-11-05T21:25:26Z</time>
+  <name>PFEIFENT</name>
+  <cmt>PFEIFENT</cmt>
+  <desc>PFEIFENT</desc>
+</wpt>
+<wpt lat="36.230449000" lon="-121.797444000">
+<time>2004-11-05T21:25:31Z</time>
+  <name>PFEIFANC</name>
+  <cmt>PFEIFANC</cmt>
+  <desc>PFEIFANC</desc>
+</wpt>
+<wpt lat="35.879801000" lon="-121.498947000">
+<time>2004-11-05T21:28:26Z</time>
+  <name>SANMRT01</name>
+  <cmt>SANMRT01</cmt>
+  <desc>SANMRT01</desc>
+</wpt>
+<wpt lat="35.652801000" lon="-121.308485000">
+<time>2004-11-05T21:28:33Z</time>
+  <name>PDRSBLNC</name>
+  <cmt>PDRSBLNC</cmt>
+  <desc>PDRSBLNC</desc>
+</wpt>
+<wpt lat="35.623297000" lon="-121.185920000">
+<time>2004-11-05T21:28:50Z</time>
+  <name>SNSMNENT</name>
+  <cmt>SNSMNENT</cmt>
+  <desc>SNSMNENT</desc>
+</wpt>
+<wpt lat="35.640478000" lon="-121.183772000">
+<time>2004-11-05T21:28:53Z</time>
+  <name>SNSMNANC</name>
+  <cmt>SNSMNANC</cmt>
+  <desc>SNSMNANC</desc>
+</wpt>
+<wpt lat="35.572353000" lon="-121.152797000">
+<time>2004-11-05T21:36:18Z</time>
+  <name>CAMBRIA</name>
+  <cmt>CAMBRIA</cmt>
+  <desc>CAMBRIA</desc>
+</wpt>
+<wpt lat="35.449214000" lon="-121.020825000">
+<time>2004-11-05T21:36:26Z</time>
+  <name>PTESTERO</name>
+  <cmt>PTESTERO</cmt>
+  <desc>PTESTERO</desc>
+</wpt>
+<wpt lat="35.216602000" lon="-120.928391000">
+<time>2004-11-05T21:36:35Z</time>
+  <name>PTBUCHON</name>
+  <cmt>PTBUCHON</cmt>
+  <desc>PTBUCHON</desc>
+</wpt>
+<wpt lat="34.883361000" lon="-120.684631000">
+<time>2004-11-05T21:36:42Z</time>
+  <name>PTSAL01</name>
+  <cmt>PTSAL01</cmt>
+  <desc>PTSAL01</desc>
+</wpt>
+<wpt lat="34.884641000" lon="-120.652026000">
+<time>2004-11-05T21:36:47Z</time>
+  <name>PTSALENT</name>
+  <cmt>A description of the Point Sal Entrance mark</cmt>
+  <desc>A description of the Point Sal Entrance mark</desc>
+</wpt>
+<wpt lat="34.896555000" lon="-120.649124000">
+<time>2004-11-05T21:37:04Z</time>
+  <name>PTSALANC</name>
+  <cmt>PTSALANC</cmt>
+  <desc>PTSALANC</desc>
+</wpt>
+<wpt lat="34.758180000" lon="-120.642516000">
+<time>2004-11-05T21:39:49Z</time>
+  <name>PURSMAPT</name>
+  <cmt>PURSMAPT</cmt>
+  <desc>PURSMAPT</desc>
+</wpt>
+<wpt lat="34.572579000" lon="-120.663636000">
+<time>2004-11-05T21:39:54Z</time>
+  <name>PTARGLLO</name>
+  <cmt>PTARGLLO</cmt>
+  <desc>PTARGLLO</desc>
+</wpt>
+<wpt lat="34.113844000" lon="-120.492630000">
+<time>2004-11-05T21:40:05Z</time>
+  <name>SANMGL01</name>
+  <cmt>SANMGL01</cmt>
+  <desc>SANMGL01</desc>
+</wpt>
+<wpt lat="34.029483000" lon="-120.471409000">
+<time>2004-11-05T21:40:44Z</time>
+  <name>SANMGL02</name>
+  <cmt>SANMGL02</cmt>
+  <desc>SANMGL02</desc>
+</wpt>
+<wpt lat="34.019184000" lon="-120.444197000">
+<time>2004-11-05T21:40:48Z</time>
+  <name>SANMGL03</name>
+  <cmt>SANMGL03</cmt>
+  <desc>SANMGL03</desc>
+</wpt>
+<wpt lat="34.023478000" lon="-120.438209000">
+<time>2004-11-05T21:40:57Z</time>
+  <name>ADCOVENT</name>
+  <cmt>ADCOVENT</cmt>
+  <desc>ADCOVENT</desc>
+</wpt>
+<wpt lat="34.028615000" lon="-120.439696000">
+<time>2004-11-05T21:40:59Z</time>
+  <name>ADCOVANC</name>
+  <cmt>ADCOVANC</cmt>
+  <desc>ADCOVANC</desc>
+</wpt>
+<rte>
+  <name>Into The Bay</name>
+  <rtept lat="37.763290" lon="-122.282580">
+<time>2004-11-05T17:09:09Z</time>
+    <name>SFBALBAY</name>
+  </rtept>
+  <rtept lat="37.751613" lon="-122.339028">
+<time>2004-11-05T17:09:10Z</time>
+    <name>SFBAY001</name>
+  </rtept>
+  <rtept lat="37.817420" lon="-122.394305">
+<time>2004-11-05T17:09:13Z</time>
+    <name>SFBAY002</name>
+  </rtept>
+  <rtept lat="37.819339" lon="-122.478302">
+<time>2004-11-05T17:09:16Z</time>
+    <name>SFGGBRDG</name>
+  </rtept>
+  <rtept lat="37.773033" lon="-122.605838">
+<time>2004-11-05T17:09:20Z</time>
+    <name>SFCHNL01</name>
+  </rtept>
+  <rtept lat="37.518860" lon="-122.529914">
+<time>2004-11-05T17:09:26Z</time>
+    <name>HMCOLREF</name>
+  </rtept>
+  <rtept lat="37.482348" lon="-122.507704">
+<time>2004-11-05T17:09:27Z</time>
+    <name>HMPILL01</name>
+  </rtept>
+  <rtept lat="37.475062" lon="-122.488531">
+<time>2004-11-05T21:16:24Z</time>
+    <name>HMPILLPT</name>
+  </rtept>
+  <rtept lat="37.476448" lon="-122.475800">
+<time>2004-11-05T17:09:29Z</time>
+    <name>HMPILL02</name>
+  </rtept>
+  <rtept lat="37.495102" lon="-122.483927">
+<time>2004-11-05T17:09:30Z</time>
+    <name>HMPILL03</name>
+  </rtept>
+</rte>
+</gpx>
diff --git a/reference/coastexp.ref2 b/reference/coastexp.ref2
new file mode 100644 (file)
index 0000000..d5a7be8
--- /dev/null
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<NavObjectCollection created="19700101T000000Z">
+       <Name>Navigation Objects</Name>
+       <Route created="19700101T000000Z" id="{00010203-0405-0607-0809-0a0b0c0d0e0f}">
+               <Marks>
+                       {10111213-1415-1617-1819-1a1b1c1d1e1f}
+                       {20212223-2425-2627-2829-2a2b2c2d2e2f}
+                       {30313233-3435-3637-3839-3a3b3c3d3e3f}
+                       {40414243-4445-4647-4849-4a4b4c4d4e4f}
+                       {50515253-5455-5657-5859-5a5b5c5d5e5f}
+                       {60616263-6465-6667-6869-6a6b6c6d6e6f}
+                       {70717273-7475-7677-7879-7a7b7c7d7e7f}
+                       {80818283-8485-8687-8889-8a8b8c8d8e8f}
+                       {90919293-9495-9697-9899-9a9b9c9d9e9f}
+                       {a0a1a2a3-a4a5-a6a7-a8a9-aaabacadaeaf}
+               </Marks>
+               <Name>Into The Bay</Name>
+       </Route>
+       <Mark created="20041105T170909Z" id="b0b1b2b3-b4b5-b6b7-b8b9-babbbcbdbebf">
+               <Position>37.763290 N 122.282580 W</Position>
+               <Name>SFBALBAY</Name>
+       </Mark>
+       <Mark created="20041105T170910Z" id="c0c1c2c3-c4c5-c6c7-c8c9-cacbcccdcecf">
+               <Position>37.751613 N 122.339028 W</Position>
+               <Name>SFBAY001</Name>
+       </Mark>
+       <Mark created="20041105T170913Z" id="d0d1d2d3-d4d5-d6d7-d8d9-dadbdcdddedf">
+               <Position>37.817420 N 122.394305 W</Position>
+               <Name>SFBAY002</Name>
+       </Mark>
+       <Mark created="20041105T170916Z" id="e0e1e2e3-e4e5-e6e7-e8e9-eaebecedeeef">
+               <Position>37.819339 N 122.478302 W</Position>
+               <Name>SFGGBRDG</Name>
+       </Mark>
+       <Mark created="20041105T170920Z" id="f0f1f2f3-f4f5-f6f7-f8f9-fafbfcfdfeff">
+               <Position>37.773033 N 122.605838 W</Position>
+               <Name>SFCHNL01</Name>
+       </Mark>
+       <Mark created="20041105T170926Z" id="00010203-0405-0607-0809-0a0b0c0d0e0f">
+               <Position>37.518860 N 122.529914 W</Position>
+               <Name>HMCOLREF</Name>
+       </Mark>
+       <Mark created="20041105T170927Z" id="10111213-1415-1617-1819-1a1b1c1d1e1f">
+               <Position>37.482348 N 122.507704 W</Position>
+               <Name>HMPILL01</Name>
+       </Mark>
+       <Mark created="20041105T211624Z" id="20212223-2425-2627-2829-2a2b2c2d2e2f">
+               <Position>37.475062 N 122.488531 W</Position>
+               <Name>HMPILLPT</Name>
+       </Mark>
+       <Mark created="20041105T170929Z" id="30313233-3435-3637-3839-3a3b3c3d3e3f">
+               <Position>37.476448 N 122.475800 W</Position>
+               <Name>HMPILL02</Name>
+       </Mark>
+       <Mark created="20041105T170930Z" id="40414243-4445-4647-4849-4a4b4c4d4e4f">
+               <Position>37.495102 N 122.483927 W</Position>
+               <Name>HMPILL03</Name>
+       </Mark>
+       <Mark created="20041105T211300Z" id="50515253-5455-5657-5859-5a5b5c5d5e5f">
+               <Position>37.229349 N 122.441589 W</Position>
+               <Name>PESCDR01</Name>
+       </Mark>
+       <Mark created="20041105T211324Z" id="60616263-6465-6667-6869-6a6b6c6d6e6f">
+               <Position>37.183397 N 122.411904 W</Position>
+               <Name>PIGEON01</Name>
+       </Mark>
+       <Mark created="20041105T211341Z" id="70717273-7475-7677-7879-7a7b7c7d7e7f">
+               <Position>37.090736 N 122.348775 W</Position>
+               <Name>ANONUV01</Name>
+       </Mark>
+       <Mark created="20041105T211409Z" id="80818283-8485-8687-8889-8a8b8c8d8e8f">
+               <Position>36.929502 N 122.113725 W</Position>
+               <Name>SCRUZ01</Name>
+       </Mark>
+       <Mark created="20041105T211416Z" id="90919293-9495-9697-9899-9a9b9c9d9e9f">
+               <Position>36.934235 N 122.022130 W</Position>
+               <Name>SCRUZ02</Name>
+       </Mark>
+       <Mark created="20041105T211420Z" id="a0a1a2a3-a4a5-a6a7-a8a9-aaabacadaeaf">
+               <Position>36.960666 N 122.024734 W</Position>
+               <Name>SCRUZENT</Name>
+       </Mark>
+       <Mark created="20041105T212422Z" id="b0b1b2b3-b4b5-b6b7-b8b9-babbbcbdbebf">
+               <Position>36.581344 N 121.995411 W</Position>
+               <Name>CYPRSSPT</Name>
+       </Mark>
+       <Mark created="20041105T212438Z" id="c0c1c2c3-c4c5-c6c7-c8c9-cacbcccdcecf">
+               <Position>36.301110 N 121.919097 W</Position>
+               <Name>PTSUR</Name>
+       </Mark>
+       <Mark created="20041105T212515Z" id="d0d1d2d3-d4d5-d6d7-d8d9-dadbdcdddedf">
+               <Position>36.238177 N 121.855209 W</Position>
+               <Name>COOPERPT</Name>
+       </Mark>
+       <Mark created="20041105T212526Z" id="e0e1e2e3-e4e5-e6e7-e8e9-eaebecedeeef">
+               <Position>36.225175 N 121.801314 W</Position>
+               <Name>PFEIFENT</Name>
+       </Mark>
+       <Mark created="20041105T212531Z" id="f0f1f2f3-f4f5-f6f7-f8f9-fafbfcfdfeff">
+               <Position>36.230449 N 121.797444 W</Position>
+               <Name>PFEIFANC</Name>
+       </Mark>
+       <Mark created="20041105T212826Z" id="00010203-0405-0607-0809-0a0b0c0d0e0f">
+               <Position>35.879801 N 121.498947 W</Position>
+               <Name>SANMRT01</Name>
+       </Mark>
+       <Mark created="20041105T212833Z" id="10111213-1415-1617-1819-1a1b1c1d1e1f">
+               <Position>35.652801 N 121.308485 W</Position>
+               <Name>PDRSBLNC</Name>
+       </Mark>
+       <Mark created="20041105T212850Z" id="20212223-2425-2627-2829-2a2b2c2d2e2f">
+               <Position>35.623297 N 121.185920 W</Position>
+               <Name>SNSMNENT</Name>
+       </Mark>
+       <Mark created="20041105T212853Z" id="30313233-3435-3637-3839-3a3b3c3d3e3f">
+               <Position>35.640478 N 121.183772 W</Position>
+               <Name>SNSMNANC</Name>
+       </Mark>
+       <Mark created="20041105T213618Z" id="40414243-4445-4647-4849-4a4b4c4d4e4f">
+               <Position>35.572353 N 121.152797 W</Position>
+               <Name>CAMBRIA</Name>
+       </Mark>
+       <Mark created="20041105T213626Z" id="50515253-5455-5657-5859-5a5b5c5d5e5f">
+               <Position>35.449214 N 121.020825 W</Position>
+               <Name>PTESTERO</Name>
+       </Mark>
+       <Mark created="20041105T213635Z" id="60616263-6465-6667-6869-6a6b6c6d6e6f">
+               <Position>35.216602 N 120.928391 W</Position>
+               <Name>PTBUCHON</Name>
+       </Mark>
+       <Mark created="20041105T213642Z" id="70717273-7475-7677-7879-7a7b7c7d7e7f">
+               <Position>34.883361 N 120.684631 W</Position>
+               <Name>PTSAL01</Name>
+       </Mark>
+       <Mark created="20041105T213647Z" id="80818283-8485-8687-8889-8a8b8c8d8e8f">
+               <Position>34.884641 N 120.652026 W</Position>
+               <Name>PTSALENT</Name>
+       </Mark>
+       <Mark created="20041105T213704Z" id="90919293-9495-9697-9899-9a9b9c9d9e9f">
+               <Position>34.896555 N 120.649124 W</Position>
+               <Name>PTSALANC</Name>
+       </Mark>
+       <Mark created="20041105T213949Z" id="a0a1a2a3-a4a5-a6a7-a8a9-aaabacadaeaf">
+               <Position>34.758180 N 120.642516 W</Position>
+               <Name>PURSMAPT</Name>
+       </Mark>
+       <Mark created="20041105T213954Z" id="b0b1b2b3-b4b5-b6b7-b8b9-babbbcbdbebf">
+               <Position>34.572579 N 120.663636 W</Position>
+               <Name>PTARGLLO</Name>
+       </Mark>
+       <Mark created="20041105T214005Z" id="c0c1c2c3-c4c5-c6c7-c8c9-cacbcccdcecf">
+               <Position>34.113844 N 120.492630 W</Position>
+               <Name>SANMGL01</Name>
+       </Mark>
+       <Mark created="20041105T214044Z" id="d0d1d2d3-d4d5-d6d7-d8d9-dadbdcdddedf">
+               <Position>34.029483 N 120.471409 W</Position>
+               <Name>SANMGL02</Name>
+       </Mark>
+       <Mark created="20041105T214048Z" id="e0e1e2e3-e4e5-e6e7-e8e9-eaebecedeeef">
+               <Position>34.019184 N 120.444197 W</Position>
+               <Name>SANMGL03</Name>
+       </Mark>
+       <Mark created="20041105T214057Z" id="f0f1f2f3-f4f5-f6f7-f8f9-fafbfcfdfeff">
+               <Position>34.023478 N 120.438209 W</Position>
+               <Name>ADCOVENT</Name>
+       </Mark>
+       <Mark created="20041105T214059Z" id="00010203-0405-0607-0809-0a0b0c0d0e0f">
+               <Position>34.028615 N 120.439696 W</Position>
+               <Name>ADCOVANC</Name>
+       </Mark>
+</NavObjectCollection>
diff --git a/reference/coastexp.ref3 b/reference/coastexp.ref3
new file mode 100644 (file)
index 0000000..9c32e36
--- /dev/null
@@ -0,0 +1,238 @@
+<?xml version="1.0"?>
+<gpx
+ version="1.0"
+creator="GPSBabel - http://www.gpsbabel.org"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.topografix.com/GPX/1/0"
+xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+<time>1970-01-01T00:00:00Z</time>
+<bounds minlat="34.019184000" minlon ="-122.605838000" maxlat="37.819339000" maxlon="-120.438209000" />
+<wpt lat="37.763290000" lon="-122.282580000">
+<time>2004-11-05T17:09:09Z</time>
+  <name>SFBALBAY</name>
+  <cmt>SFBALBAY</cmt>
+  <desc>SFBALBAY</desc>
+</wpt>
+<wpt lat="37.751613000" lon="-122.339028000">
+<time>2004-11-05T17:09:10Z</time>
+  <name>SFBAY001</name>
+  <cmt>SFBAY001</cmt>
+  <desc>SFBAY001</desc>
+</wpt>
+<wpt lat="37.817420000" lon="-122.394305000">
+<time>2004-11-05T17:09:13Z</time>
+  <name>SFBAY002</name>
+  <cmt>SFBAY002</cmt>
+  <desc>SFBAY002</desc>
+</wpt>
+<wpt lat="37.819339000" lon="-122.478302000">
+<time>2004-11-05T17:09:16Z</time>
+  <name>SFGGBRDG</name>
+  <cmt>SFGGBRDG</cmt>
+  <desc>SFGGBRDG</desc>
+</wpt>
+<wpt lat="37.773033000" lon="-122.605838000">
+<time>2004-11-05T17:09:20Z</time>
+  <name>SFCHNL01</name>
+  <cmt>SFCHNL01</cmt>
+  <desc>SFCHNL01</desc>
+</wpt>
+<wpt lat="37.518860000" lon="-122.529914000">
+<time>2004-11-05T17:09:26Z</time>
+  <name>HMCOLREF</name>
+  <cmt>HMCOLREF</cmt>
+  <desc>HMCOLREF</desc>
+</wpt>
+<wpt lat="37.482348000" lon="-122.507704000">
+<time>2004-11-05T17:09:27Z</time>
+  <name>HMPILL01</name>
+  <cmt>HMPILL01</cmt>
+  <desc>HMPILL01</desc>
+</wpt>
+<wpt lat="37.476448000" lon="-122.475800000">
+<time>2004-11-05T17:09:29Z</time>
+  <name>HMPILL02</name>
+  <cmt>HMPILL02</cmt>
+  <desc>HMPILL02</desc>
+</wpt>
+<wpt lat="37.495102000" lon="-122.483927000">
+<time>2004-11-05T17:09:30Z</time>
+  <name>HMPILL03</name>
+  <cmt>HMPILL03</cmt>
+  <desc>HMPILL03</desc>
+</wpt>
+<wpt lat="37.229349000" lon="-122.441589000">
+<time>2004-11-05T21:13:00Z</time>
+  <name>PESCDR01</name>
+  <cmt>PESCDR01</cmt>
+  <desc>PESCDR01</desc>
+</wpt>
+<wpt lat="37.183397000" lon="-122.411904000">
+<time>2004-11-05T21:13:24Z</time>
+  <name>PIGEON01</name>
+  <cmt>PIGEON01</cmt>
+  <desc>PIGEON01</desc>
+</wpt>
+<wpt lat="37.090736000" lon="-122.348775000">
+<time>2004-11-05T21:13:41Z</time>
+  <name>ANONUV01</name>
+  <cmt>ANONUV01</cmt>
+  <desc>ANONUV01</desc>
+</wpt>
+<wpt lat="36.929502000" lon="-122.113725000">
+<time>2004-11-05T21:14:09Z</time>
+  <name>SCRUZ01</name>
+  <cmt>SCRUZ01</cmt>
+  <desc>SCRUZ01</desc>
+</wpt>
+<wpt lat="36.934235000" lon="-122.022130000">
+<time>2004-11-05T21:14:16Z</time>
+  <name>SCRUZ02</name>
+  <cmt>SCRUZ02</cmt>
+  <desc>SCRUZ02</desc>
+</wpt>
+<wpt lat="36.960666000" lon="-122.024734000">
+<time>2004-11-05T21:14:20Z</time>
+  <name>SCRUZENT</name>
+  <cmt>SCRUZENT</cmt>
+  <desc>SCRUZENT</desc>
+</wpt>
+<wpt lat="37.475062000" lon="-122.488531000">
+<time>2004-11-05T21:16:24Z</time>
+  <name>HMPILLPT</name>
+  <cmt>HMPILLPT</cmt>
+  <desc>HMPILLPT</desc>
+</wpt>
+<wpt lat="36.581344000" lon="-121.995411000">
+<time>2004-11-05T21:24:22Z</time>
+  <name>CYPRSSPT</name>
+  <cmt>CYPRSSPT</cmt>
+  <desc>CYPRSSPT</desc>
+</wpt>
+<wpt lat="36.301110000" lon="-121.919097000">
+<time>2004-11-05T21:24:38Z</time>
+  <name>PTSUR</name>
+  <cmt>PTSUR</cmt>
+  <desc>PTSUR</desc>
+</wpt>
+<wpt lat="36.238177000" lon="-121.855209000">
+<time>2004-11-05T21:25:15Z</time>
+  <name>COOPERPT</name>
+  <cmt>COOPERPT</cmt>
+  <desc>COOPERPT</desc>
+</wpt>
+<wpt lat="36.225175000" lon="-121.801314000">
+<time>2004-11-05T21:25:26Z</time>
+  <name>PFEIFENT</name>
+  <cmt>PFEIFENT</cmt>
+  <desc>PFEIFENT</desc>
+</wpt>
+<wpt lat="36.230449000" lon="-121.797444000">
+<time>2004-11-05T21:25:31Z</time>
+  <name>PFEIFANC</name>
+  <cmt>PFEIFANC</cmt>
+  <desc>PFEIFANC</desc>
+</wpt>
+<wpt lat="35.879801000" lon="-121.498947000">
+<time>2004-11-05T21:28:26Z</time>
+  <name>SANMRT01</name>
+  <cmt>SANMRT01</cmt>
+  <desc>SANMRT01</desc>
+</wpt>
+<wpt lat="35.652801000" lon="-121.308485000">
+<time>2004-11-05T21:28:33Z</time>
+  <name>PDRSBLNC</name>
+  <cmt>PDRSBLNC</cmt>
+  <desc>PDRSBLNC</desc>
+</wpt>
+<wpt lat="35.623297000" lon="-121.185920000">
+<time>2004-11-05T21:28:50Z</time>
+  <name>SNSMNENT</name>
+  <cmt>SNSMNENT</cmt>
+  <desc>SNSMNENT</desc>
+</wpt>
+<wpt lat="35.640478000" lon="-121.183772000">
+<time>2004-11-05T21:28:53Z</time>
+  <name>SNSMNANC</name>
+  <cmt>SNSMNANC</cmt>
+  <desc>SNSMNANC</desc>
+</wpt>
+<wpt lat="35.572353000" lon="-121.152797000">
+<time>2004-11-05T21:36:18Z</time>
+  <name>CAMBRIA</name>
+  <cmt>CAMBRIA</cmt>
+  <desc>CAMBRIA</desc>
+</wpt>
+<wpt lat="35.449214000" lon="-121.020825000">
+<time>2004-11-05T21:36:26Z</time>
+  <name>PTESTERO</name>
+  <cmt>PTESTERO</cmt>
+  <desc>PTESTERO</desc>
+</wpt>
+<wpt lat="35.216602000" lon="-120.928391000">
+<time>2004-11-05T21:36:35Z</time>
+  <name>PTBUCHON</name>
+  <cmt>PTBUCHON</cmt>
+  <desc>PTBUCHON</desc>
+</wpt>
+<wpt lat="34.883361000" lon="-120.684631000">
+<time>2004-11-05T21:36:42Z</time>
+  <name>PTSAL01</name>
+  <cmt>PTSAL01</cmt>
+  <desc>PTSAL01</desc>
+</wpt>
+<wpt lat="34.884641000" lon="-120.652026000">
+<time>2004-11-05T21:36:47Z</time>
+  <name>PTSALENT</name>
+  <cmt>A description of the Point Sal Entrance mark</cmt>
+  <desc>A description of the Point Sal Entrance mark</desc>
+</wpt>
+<wpt lat="34.896555000" lon="-120.649124000">
+<time>2004-11-05T21:37:04Z</time>
+  <name>PTSALANC</name>
+  <cmt>PTSALANC</cmt>
+  <desc>PTSALANC</desc>
+</wpt>
+<wpt lat="34.758180000" lon="-120.642516000">
+<time>2004-11-05T21:39:49Z</time>
+  <name>PURSMAPT</name>
+  <cmt>PURSMAPT</cmt>
+  <desc>PURSMAPT</desc>
+</wpt>
+<wpt lat="34.572579000" lon="-120.663636000">
+<time>2004-11-05T21:39:54Z</time>
+  <name>PTARGLLO</name>
+  <cmt>PTARGLLO</cmt>
+  <desc>PTARGLLO</desc>
+</wpt>
+<wpt lat="34.113844000" lon="-120.492630000">
+<time>2004-11-05T21:40:05Z</time>
+  <name>SANMGL01</name>
+  <cmt>SANMGL01</cmt>
+  <desc>SANMGL01</desc>
+</wpt>
+<wpt lat="34.029483000" lon="-120.471409000">
+<time>2004-11-05T21:40:44Z</time>
+  <name>SANMGL02</name>
+  <cmt>SANMGL02</cmt>
+  <desc>SANMGL02</desc>
+</wpt>
+<wpt lat="34.019184000" lon="-120.444197000">
+<time>2004-11-05T21:40:48Z</time>
+  <name>SANMGL03</name>
+  <cmt>SANMGL03</cmt>
+  <desc>SANMGL03</desc>
+</wpt>
+<wpt lat="34.023478000" lon="-120.438209000">
+<time>2004-11-05T21:40:57Z</time>
+  <name>ADCOVENT</name>
+  <cmt>ADCOVENT</cmt>
+  <desc>ADCOVENT</desc>
+</wpt>
+<wpt lat="34.028615000" lon="-120.439696000">
+<time>2004-11-05T21:40:59Z</time>
+  <name>ADCOVANC</name>
+  <cmt>ADCOVANC</cmt>
+  <desc>ADCOVANC</desc>
+</wpt>
+</gpx>
diff --git a/reference/coastexp.ref4 b/reference/coastexp.ref4
new file mode 100644 (file)
index 0000000..20faa6a
--- /dev/null
@@ -0,0 +1,156 @@
+<?xml version="1.0"?>
+<NavObjectCollection created="19700101T000000Z">
+       <Name>Navigation Objects</Name>
+       <Mark created="20041105T170909Z" id="00010203-0405-0607-0809-0a0b0c0d0e0f">
+               <Position>37.763290 N 122.282580 W</Position>
+               <Name>SFBALBAY</Name>
+       </Mark>
+       <Mark created="20041105T170910Z" id="10111213-1415-1617-1819-1a1b1c1d1e1f">
+               <Position>37.751613 N 122.339028 W</Position>
+               <Name>SFBAY001</Name>
+       </Mark>
+       <Mark created="20041105T170913Z" id="20212223-2425-2627-2829-2a2b2c2d2e2f">
+               <Position>37.817420 N 122.394305 W</Position>
+               <Name>SFBAY002</Name>
+       </Mark>
+       <Mark created="20041105T170916Z" id="30313233-3435-3637-3839-3a3b3c3d3e3f">
+               <Position>37.819339 N 122.478302 W</Position>
+               <Name>SFGGBRDG</Name>
+       </Mark>
+       <Mark created="20041105T170920Z" id="40414243-4445-4647-4849-4a4b4c4d4e4f">
+               <Position>37.773033 N 122.605838 W</Position>
+               <Name>SFCHNL01</Name>
+       </Mark>
+       <Mark created="20041105T170926Z" id="50515253-5455-5657-5859-5a5b5c5d5e5f">
+               <Position>37.518860 N 122.529914 W</Position>
+               <Name>HMCOLREF</Name>
+       </Mark>
+       <Mark created="20041105T170927Z" id="60616263-6465-6667-6869-6a6b6c6d6e6f">
+               <Position>37.482348 N 122.507704 W</Position>
+               <Name>HMPILL01</Name>
+       </Mark>
+       <Mark created="20041105T170929Z" id="70717273-7475-7677-7879-7a7b7c7d7e7f">
+               <Position>37.476448 N 122.475800 W</Position>
+               <Name>HMPILL02</Name>
+       </Mark>
+       <Mark created="20041105T170930Z" id="80818283-8485-8687-8889-8a8b8c8d8e8f">
+               <Position>37.495102 N 122.483927 W</Position>
+               <Name>HMPILL03</Name>
+       </Mark>
+       <Mark created="20041105T211300Z" id="90919293-9495-9697-9899-9a9b9c9d9e9f">
+               <Position>37.229349 N 122.441589 W</Position>
+               <Name>PESCDR01</Name>
+       </Mark>
+       <Mark created="20041105T211324Z" id="a0a1a2a3-a4a5-a6a7-a8a9-aaabacadaeaf">
+               <Position>37.183397 N 122.411904 W</Position>
+               <Name>PIGEON01</Name>
+       </Mark>
+       <Mark created="20041105T211341Z" id="b0b1b2b3-b4b5-b6b7-b8b9-babbbcbdbebf">
+               <Position>37.090736 N 122.348775 W</Position>
+               <Name>ANONUV01</Name>
+       </Mark>
+       <Mark created="20041105T211409Z" id="c0c1c2c3-c4c5-c6c7-c8c9-cacbcccdcecf">
+               <Position>36.929502 N 122.113725 W</Position>
+               <Name>SCRUZ01</Name>
+       </Mark>
+       <Mark created="20041105T211416Z" id="d0d1d2d3-d4d5-d6d7-d8d9-dadbdcdddedf">
+               <Position>36.934235 N 122.022130 W</Position>
+               <Name>SCRUZ02</Name>
+       </Mark>
+       <Mark created="20041105T211420Z" id="e0e1e2e3-e4e5-e6e7-e8e9-eaebecedeeef">
+               <Position>36.960666 N 122.024734 W</Position>
+               <Name>SCRUZENT</Name>
+       </Mark>
+       <Mark created="20041105T211624Z" id="f0f1f2f3-f4f5-f6f7-f8f9-fafbfcfdfeff">
+               <Position>37.475062 N 122.488531 W</Position>
+               <Name>HMPILLPT</Name>
+       </Mark>
+       <Mark created="20041105T212422Z" id="00010203-0405-0607-0809-0a0b0c0d0e0f">
+               <Position>36.581344 N 121.995411 W</Position>
+               <Name>CYPRSSPT</Name>
+       </Mark>
+       <Mark created="20041105T212438Z" id="10111213-1415-1617-1819-1a1b1c1d1e1f">
+               <Position>36.301110 N 121.919097 W</Position>
+               <Name>PTSUR</Name>
+       </Mark>
+       <Mark created="20041105T212515Z" id="20212223-2425-2627-2829-2a2b2c2d2e2f">
+               <Position>36.238177 N 121.855209 W</Position>
+               <Name>COOPERPT</Name>
+       </Mark>
+       <Mark created="20041105T212526Z" id="30313233-3435-3637-3839-3a3b3c3d3e3f">
+               <Position>36.225175 N 121.801314 W</Position>
+               <Name>PFEIFENT</Name>
+       </Mark>
+       <Mark created="20041105T212531Z" id="40414243-4445-4647-4849-4a4b4c4d4e4f">
+               <Position>36.230449 N 121.797444 W</Position>
+               <Name>PFEIFANC</Name>
+       </Mark>
+       <Mark created="20041105T212826Z" id="50515253-5455-5657-5859-5a5b5c5d5e5f">
+               <Position>35.879801 N 121.498947 W</Position>
+               <Name>SANMRT01</Name>
+       </Mark>
+       <Mark created="20041105T212833Z" id="60616263-6465-6667-6869-6a6b6c6d6e6f">
+               <Position>35.652801 N 121.308485 W</Position>
+               <Name>PDRSBLNC</Name>
+       </Mark>
+       <Mark created="20041105T212850Z" id="70717273-7475-7677-7879-7a7b7c7d7e7f">
+               <Position>35.623297 N 121.185920 W</Position>
+               <Name>SNSMNENT</Name>
+       </Mark>
+       <Mark created="20041105T212853Z" id="80818283-8485-8687-8889-8a8b8c8d8e8f">
+               <Position>35.640478 N 121.183772 W</Position>
+               <Name>SNSMNANC</Name>
+       </Mark>
+       <Mark created="20041105T213618Z" id="90919293-9495-9697-9899-9a9b9c9d9e9f">
+               <Position>35.572353 N 121.152797 W</Position>
+               <Name>CAMBRIA</Name>
+       </Mark>
+       <Mark created="20041105T213626Z" id="a0a1a2a3-a4a5-a6a7-a8a9-aaabacadaeaf">
+               <Position>35.449214 N 121.020825 W</Position>
+               <Name>PTESTERO</Name>
+       </Mark>
+       <Mark created="20041105T213635Z" id="b0b1b2b3-b4b5-b6b7-b8b9-babbbcbdbebf">
+               <Position>35.216602 N 120.928391 W</Position>
+               <Name>PTBUCHON</Name>
+       </Mark>
+       <Mark created="20041105T213642Z" id="c0c1c2c3-c4c5-c6c7-c8c9-cacbcccdcecf">
+               <Position>34.883361 N 120.684631 W</Position>
+               <Name>PTSAL01</Name>
+       </Mark>
+       <Mark created="20041105T213647Z" id="d0d1d2d3-d4d5-d6d7-d8d9-dadbdcdddedf">
+               <Position>34.884641 N 120.652026 W</Position>
+               <Name>PTSALENT</Name>
+       </Mark>
+       <Mark created="20041105T213704Z" id="e0e1e2e3-e4e5-e6e7-e8e9-eaebecedeeef">
+               <Position>34.896555 N 120.649124 W</Position>
+               <Name>PTSALANC</Name>
+       </Mark>
+       <Mark created="20041105T213949Z" id="f0f1f2f3-f4f5-f6f7-f8f9-fafbfcfdfeff">
+               <Position>34.758180 N 120.642516 W</Position>
+               <Name>PURSMAPT</Name>
+       </Mark>
+       <Mark created="20041105T213954Z" id="00010203-0405-0607-0809-0a0b0c0d0e0f">
+               <Position>34.572579 N 120.663636 W</Position>
+               <Name>PTARGLLO</Name>
+       </Mark>
+       <Mark created="20041105T214005Z" id="10111213-1415-1617-1819-1a1b1c1d1e1f">
+               <Position>34.113844 N 120.492630 W</Position>
+               <Name>SANMGL01</Name>
+       </Mark>
+       <Mark created="20041105T214044Z" id="20212223-2425-2627-2829-2a2b2c2d2e2f">
+               <Position>34.029483 N 120.471409 W</Position>
+               <Name>SANMGL02</Name>
+       </Mark>
+       <Mark created="20041105T214048Z" id="30313233-3435-3637-3839-3a3b3c3d3e3f">
+               <Position>34.019184 N 120.444197 W</Position>
+               <Name>SANMGL03</Name>
+       </Mark>
+       <Mark created="20041105T214057Z" id="40414243-4445-4647-4849-4a4b4c4d4e4f">
+               <Position>34.023478 N 120.438209 W</Position>
+               <Name>ADCOVENT</Name>
+       </Mark>
+       <Mark created="20041105T214059Z" id="50515253-5455-5657-5859-5a5b5c5d5e5f">
+               <Position>34.028615 N 120.439696 W</Position>
+               <Name>ADCOVANC</Name>
+       </Mark>
+</NavObjectCollection>
diff --git a/reference/foo.an1 b/reference/foo.an1
new file mode 100644 (file)
index 0000000..ae27a48
Binary files /dev/null and b/reference/foo.an1 differ
diff --git a/reference/google.arc b/reference/google.arc
new file mode 100644 (file)
index 0000000..c216f18
--- /dev/null
@@ -0,0 +1,111 @@
+41.87895       -87.63665
+41.87924       -87.63666
+41.87937       -87.63666
+41.87952       -87.63667
+41.88063       -87.63672
+41.88126       -87.63673
+41.88194       -87.63676
+41.88194       -87.63676
+41.88206       -87.63676
+41.88257       -87.63678
+41.88301       -87.63679
+41.88318       -87.63678
+41.88380       -87.63681
+41.88447       -87.63683
+41.88506       -87.63686
+41.88519       -87.63686
+41.88542       -87.63686
+41.88574       -87.63682
+41.88574       -87.63682
+41.88583       -87.63678
+41.88595       -87.63666
+41.88677       -87.63538
+41.88677       -87.63528
+41.88677       -87.63477
+41.88677       -87.63394
+41.88677       -87.63249
+41.88677       -87.63249
+41.88696       -87.63248
+41.88710       -87.63248
+41.88780       -87.63248
+41.88780       -87.63248
+41.88919       -87.63254
+41.89000       -87.63254
+41.89078       -87.63257
+41.89160       -87.63260
+41.89198       -87.63261
+41.89240       -87.63263
+41.89322       -87.63264
+41.89401       -87.63266
+41.89482       -87.63267
+41.89562       -87.63269
+41.89664       -87.63271
+41.89796       -87.63273
+41.89926       -87.63278
+41.90053       -87.63283
+41.90183       -87.63288
+41.90312       -87.63290
+41.90388       -87.63292
+41.90576       -87.63300
+41.90772       -87.63305
+41.90917       -87.63309
+41.91117       -87.63313
+41.91117       -87.63313
+41.91265       -87.63317
+41.91289       -87.63316
+41.91289       -87.63316
+41.91299       -87.63310
+41.91307       -87.63301
+41.91314       -87.63284
+41.91314       -87.63284
+41.91380       -87.63324
+41.91485       -87.63388
+41.91560       -87.63433
+41.91658       -87.63494
+41.91842       -87.63603
+41.91842       -87.63603
+41.91889       -87.63636
+41.92015       -87.63718
+41.92195       -87.63822
+41.92374       -87.63928
+41.92497       -87.64005
+41.92556       -87.64040
+41.92678       -87.64115
+41.92697       -87.64127
+41.92730       -87.64147
+41.92778       -87.64172
+41.92852       -87.64217
+41.92865       -87.64224
+41.92951       -87.64276
+41.92963       -87.64288
+41.92982       -87.64311
+41.92995       -87.64335
+41.93067       -87.64382
+41.93131       -87.64418
+41.93180       -87.64449
+41.93208       -87.64466
+41.93242       -87.64479
+41.93277       -87.64483
+41.93277       -87.64483
+41.93368       -87.64551
+41.93452       -87.64622
+41.93478       -87.64645
+41.93549       -87.64700
+41.93558       -87.64707
+41.93639       -87.64774
+41.93780       -87.64888
+41.93811       -87.64913
+41.93811       -87.64913
+41.93903       -87.64986
+41.93992       -87.65062
+41.94175       -87.65203
+41.94241       -87.65255
+41.94352       -87.65349
+41.94429       -87.65410
+41.94429       -87.65410
+41.94443       -87.65420
+41.94558       -87.65510
+41.94654       -87.65592
+41.94718       -87.65639
+41.94718       -87.65639
+41.94719       -87.65553
diff --git a/reference/google.js b/reference/google.js
new file mode 100644 (file)
index 0000000..de2e30b
--- /dev/null
@@ -0,0 +1,2 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"/><title>Google Maps - 233 S. Wacker, Chicago, IL to 1060 W. Addison, Chicago, IL</title><script type="text/javascript">//<![CDATA[
+function vpage_load() {if (window.parent && window.parent._load) {window.parent._load('<?xml version="1.0"?><page><title>233 S. Wacker, Chicago, IL to 1060 W. Addison, Chicago, IL</title><query>233 S. Wacker, Chicago, IL to 1060 W. Addison, Chicago, IL</query><center lat="41.913070" lng="-87.644435"/><span lat="0.068240" lng="0.023910"/><directions><source><address><line>233 S Upper Wacker Dr</line><line>Chicago, IL 60606</line></address></source><destination><address><line>1060 W Addison St</line><line>Chicago, IL 60613</line></address></destination><polyline numLevels="4" zoomFactor="32"><points>mnr~F`p{uOy@@Y?]@}EH}B@gCD??W?eBBwA@a@A{BDeCBuBDY?m@?_AG??QGWWcD_G?S?eB?eD?aH??e@A[?kC???uGJaD?{CDcDDkA@sABcD@}CBaD@_DBkEBgGBcGH}FHcGHaGBwCBwJNgKHaHFoKF??gHFo@A??SKOQMa@??cCnAqE~BuCxAcExBoJxE??}A`A{FbDgJnEeJrEuFxCuBdAsFtCe@VaAf@_Bp@sCxAYLkDfBWVe@l@Yn@oC|A_CfAaB|@w@`@cAXeAF??uDfCgDlCs@l@mClBQLaDdCyGbF}@p@??wDpCqDvCmJxGcCfB}EzDyCxB??[ReFrD_EbD_C|A??AkD</points><levels>B?????BB??????@??BB?@@???BB??BB?????@?????@?????@??BB?BB?@BB????@??@?@????@???@?@@@??@@A?@?????????@?@@?????BBB</levels></polyline><segments meters="8443" seconds="543" distance="5.2 mi" time="9 mins"><segment id="seg0" pointIndex="0" meters="332" seconds="21" distance="0.2 mi" time="21 secs">Head  <b>north</b> from <b>S Upper Wacker Dr</b></segment><segment id="seg1" pointIndex="7" meters="422" seconds="27" distance="0.3 mi" time="27 secs">Continue on <b>N Upper Wacker Dr</b></segment><segment id="seg2" pointIndex="18" meters="406" seconds="26" distance="0.3 mi" time="26 secs">Bear <b>right</b> at <b>W Upper Wacker Dr</b></segment><segment id="seg3" pointIndex="26" meters="114" seconds="7" distance="0.1 mi" time="7 secs">Turn <b>left</b> at <b>N La Salle St</b></segment><segment id="seg4" pointIndex="30" meters="2597" seconds="167" distance="1.6 mi" time="2 mins">Continue on <b>N La Salle Blvd</b></segment><segment id="seg5" pointIndex="52" meters="191" seconds="12" distance="0.1 mi" time="12 secs">Continue on <b>N La Salle Dr</b></segment><segment id="seg6" pointIndex="55" meters="40" seconds="3" distance="0.0 mi" time="2 secs">Bear <b>right</b> at <b>W Eugenie St</b></segment><segment id="seg7" pointIndex="59" meters="4269" seconds="274" distance="2.7 mi" time="4 mins">Turn <b>left</b> at <b>N Clark St</b></segment><segment id="seg8" pointIndex="109" meters="71" seconds="5" distance="0.0 mi" time="4 secs">Turn <b>right</b> at <b>W Addison St</b></segment></segments></directions></page>', window.document);}}//]]></script></head><body onload="vpage_load()"><input id="zoom" type="text" value=""/><input id="centerlat" type="text" value=""/><input id="centerlng" type="text" value=""/></body></html>
\ No newline at end of file
diff --git a/reference/google.xml b/reference/google.xml
new file mode 100644 (file)
index 0000000..33ff7f3
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0"?><page><title>233 S. Wacker, Chicago, IL to 1060 W. Addison, Chicago, IL</title><query>233 S. Wacker, Chicago, IL to 1060 W. Addison, Chicago, IL</query><center lat="41.913070" lng="-87.644435"/><span lat="0.068240" lng="0.023910"/><directions><source><address><line>233 S Upper Wacker Dr</line><line>Chicago, IL 60606</line></address></source><destination><address><line>1060 W Addison St</line><line>Chicago, IL 60613</line></address></destination><polyline numLevels="4" zoomFactor="32"><points>mnr~F`p{uOy@@Y?]@}EH}B@gCD??W?eBBwA@a@A{BDeCBuBDY?m@?_AG??QGWWcD_G?S?eB?eD?aH??e@A[?kC???uGJaD?{CDcDDkA@sABcD@}CBaD@_DBkEBgGBcGH}FHcGHaGBwCBwJNgKHaHFoKF??gHFo@A??SKOQMa@??cCnAqE~BuCxAcExBoJxE??}A`A{FbDgJnEeJrEuFxCuBdAsFtCe@VaAf@_Bp@sCxAYLkDfBWVe@l@Yn@oC|A_CfAaB|@w@`@cAXeAF??uDfCgDlCs@l@mClBQLaDdCyGbF}@p@??wDpCqDvCmJxGcCfB}EzDyCxB??[ReFrD_EbD_C|A??AkD</points><levels>B?????BB??????@??BB?@@???BB??BB?????@?????@?????@??BB?BB?@BB????@??@?@????@???@?@@@??@@A?@?????????@?@@?????BBB</levels></polyline><segments meters="8443" seconds="543" distance="5.2 mi" time="9 mins"><segment id="seg0" pointIndex="0" meters="332" seconds="21" distance="0.2 mi" time="21 secs">Head  <b>north</b> from <b>S Upper Wacker Dr</b></segment><segment id="seg1" pointIndex="7" meters="422" seconds="27" distance="0.3 mi" time="27 secs">Continue on <b>N Upper Wacker Dr</b></segment><segment id="seg2" pointIndex="18" meters="406" seconds="26" distance="0.3 mi" time="26 secs">Bear <b>right</b> at <b>W Upper Wacker Dr</b></segment><segment id="seg3" pointIndex="26" meters="114" seconds="7" distance="0.1 mi" time="7 secs">Turn <b>left</b> at <b>N La Salle St</b></segment><segment id="seg4" pointIndex="30" meters="2597" seconds="167" distance="1.6 mi" time="2 mins">Continue on <b>N La Salle Blvd</b></segment><segment id="seg5" pointIndex="52" meters="191" seconds="12" distance="0.1 mi" time="12 secs">Continue on <b>N La Salle Dr</b></segment><segment id="seg6" pointIndex="55" meters="40" seconds="3" distance="0.0 mi" time="2 secs">Bear <b>right</b> at <b>W Eugenie St</b></segment><segment id="seg7" pointIndex="59" meters="4269" seconds="274" distance="2.7 mi" time="4 mins">Turn <b>left</b> at <b>N Clark St</b></segment><segment id="seg8" pointIndex="109" meters="71" seconds="5" distance="0.0 mi" time="4 secs">Turn <b>right</b> at <b>W Addison St</b></segment></segments></directions></page>
\ No newline at end of file
diff --git a/reference/googmap.sh b/reference/googmap.sh
new file mode 100644 (file)
index 0000000..83a73d3
--- /dev/null
@@ -0,0 +1,5 @@
+
+FROM="233 S. Wacker, Chicago, IL"
+TO="1060 W. Addison, Chicago, IL"
+wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=xml" 2>/dev/null
+
diff --git a/reference/googmapjs.sh b/reference/googmapjs.sh
new file mode 100644 (file)
index 0000000..6ce5318
--- /dev/null
@@ -0,0 +1,5 @@
+
+FROM="233 S. Wacker, Chicago, IL"
+TO="1060 W. Addison, Chicago, IL"
+wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" 2>/dev/null
+
index 78c979a7d870e935bccfe2521a1bbeca5dbb54b8..0f3b43070b9e893a16c4846db7556064c0ce571a 100644 (file)
@@ -6,72 +6,72 @@
                <LastModified>0</LastModified>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGCEBB\1flegnum0\1fusrmrkMountain Bike Heaven by susy1313\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGCEBB\1flegnum0\1fusrmrkMountain Bike Heaven by susy1313\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>35.972033</Latitude>
                        <Longitude>-87.134700</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC1A37\1flegnum1\1fusrmrkThe Troll by a182pilot & Family\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC1A37\1flegnum1\1fusrmrkThe Troll by a182pilot & Family\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>36.090683</Latitude>
                        <Longitude>-86.679550</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC1C2B\1flegnum2\1fusrmrkDive Bomber by JoGPS & family\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC1C2B\1flegnum2\1fusrmrkDive Bomber by JoGPS & family\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>35.996267</Latitude>
                        <Longitude>-86.620117</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC25A9\1flegnum3\1fusrmrkFOSTER by JoGPS & Family\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC25A9\1flegnum3\1fusrmrkFOSTER by JoGPS & Family\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>36.038483</Latitude>
                        <Longitude>-86.648617</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC2723\1flegnum4\1fusrmrkLogan Lighthouse by JoGps & Family\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC2723\1flegnum4\1fusrmrkLogan Lighthouse by JoGps & Family\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>36.112183</Latitude>
                        <Longitude>-86.741767</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC2B71\1flegnum5\1fusrmrkGanier Cache by Susy1313\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC2B71\1flegnum5\1fusrmrkGanier Cache by Susy1313\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>36.064083</Latitude>
                        <Longitude>-86.790517</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC309F\1flegnum6\1fusrmrkShy's Hill by FireFighterEng33\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC309F\1flegnum6\1fusrmrkShy's Hill by FireFighterEng33\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>36.087767</Latitude>
                        <Longitude>-86.809733</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC317A\1flegnum7\1fusrmrkGittyUp by JoGPS / Warner Parks\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC317A\1flegnum7\1fusrmrkGittyUp by JoGPS / Warner Parks\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>36.057500</Latitude>
                        <Longitude>-86.892000</Longitude>
                </Object>
                <Object>
                        <ClassName>waypnt</ClassName>
-                       <Attr>attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC317D\1flegnum8\1fusrmrkInlighting by JoGPS / Warner Parks\1fselect2\1f</Attr>
-                       <LegAttr>attr=grpnamROUTENAME\1f</LegAttr>
+                       <Attr><![CDATA[attr=grpnamROUTENAME\1ftrnrad50\1fOBJNAMGC317D\1flegnum8\1fusrmrkInlighting by JoGPS / Warner Parks\1fselect2\1f]]></Attr>
+                       <LegAttr><![CDATA[attr=grpnamROUTENAME\1f]]></LegAttr>
                        <NumberOfVertexs>1</NumberOfVertexs>
                        <Latitude>36.082800</Latitude>
                        <Longitude>-86.867283</Longitude>
index 35191c176ec5a5b5c27070a3f42866c1cfed21ba..63e3ef55d200f30a1d23b071a705b344b88880bc 100644 (file)
@@ -1,30 +1,45 @@
 <?xml version="1.0"?>
 <gpx
  version="1.0"
-creator="GPSBabel - http://gpsbabel.sourceforge.net"
+creator="GPSBabel - http://www.gpsbabel.org"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.topografix.com/GPX/1/0"
 xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
-<time>2004-08-25T09:57:00Z</time>
-<bounds minlat="-35.498071" minlon ="148.115814" maxlat="-27.755478" maxlon="153.042490" />
-<wpt lat="-29.480116" lon="150.133619">
+<time>2005-01-18T18:58:35Z</time>
+<bounds minlat="-30.342870000" minlon ="149.746093000" maxlat="-27.755478000" maxlon="150.477059000" />
+<wpt lat="-29.480116000" lon="150.133619000">
   <name>PALLMG</name>
   <cmt>PALLMG</cmt>
   <desc>PALLMG</desc>
   <sym>dot</sym>
 </wpt>
-<wpt lat="-27.755478" lon="149.746093">
+<wpt lat="-27.755478000" lon="149.746093000">
   <name>PILOT</name>
   <cmt>CHRIS JONES</cmt>
   <desc>CHRIS JONES</desc>
   <sym>dot</sym>
 </wpt>
-<wpt lat="-30.342870" lon="150.477059">
+<wpt lat="-30.342870000" lon="150.477059000">
   <name>PLUMTH</name>
   <cmt>PLUMTHORPE LOC</cmt>
   <desc>PLUMTHORPE LOC</desc>
   <sym>dot</sym>
 </wpt>
+<rte>
+  <name>AB1</name>
+  <rtept lat="-30.675867" lon="150.609035">
+    <ele>0.000000</ele>
+    <name>BORAH </name>
+  </rtept>
+  <rtept lat="-30.729929" lon="150.649193">
+    <ele>0.000000</ele>
+    <name>BALDWI</name>
+  </rtept>
+  <rtept lat="-30.763677" lon="150.723195">
+    <ele>0.000000</ele>
+    <name>MANAIR</name>
+  </rtept>
+</rte>
 <trk>
 <trkseg>
 <trkpt lat="-30.747492" lon="150.720524">
@@ -531,19 +546,4 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/
 </trkpt>
 </trkseg>
 </trk>
-<rte>
-  <name>AB1</name>
-  <rtept lat="-30.675867" lon="150.609035">
-    <ele>0.000000</ele>
-    <name>BORAH </name>
-  </rtept>
-  <rtept lat="-30.729929" lon="150.649193">
-    <ele>0.000000</ele>
-    <name>BALDWI</name>
-  </rtept>
-  <rtept lat="-30.763677" lon="150.723195">
-    <ele>0.000000</ele>
-    <name>MANAIR</name>
-  </rtept>
-</rte>
 </gpx>
index 21ff7744a42b9ceb8c4649465717ed7927be7791..2ecdeb4e2f7e4a81be3e9759f51f7f9ad4b1c1b1 100644 (file)
@@ -48,7 +48,7 @@ B0419123040526S15036253EA0090600000
 B0419433040646S15036334EA0090300000\r
 B0420133040794S15036367EA0089500000\r
 B0420443040707S15036367EA0090300000\r
-B0421143040678S15036423EA0092200000\r
+B0421143040679S15036423EA0092200000\r
 B0421443040658S15036414EA0091400000\r
 B0422153040772S15036358EA0091900000\r
 B0422453040722S15036423EA0096100000\r
index 9dc64d8885378ef1c802522a7b84e501ec046336..25c86bb95444fa0f5531eead08f9e96195e42916 100644 (file)
@@ -6,6 +6,30 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.topografix.com/GPX/1/0"
 xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
 <time>1970-01-01T00:00:00Z</time>
+<rte>
+  <name>0001</name>
+  <desc>IGCDATE000000: </desc>
+  <rtept lat="-30.675867" lon="150.609033">
+    <name>TAKEOFF</name>
+    <cmt>BORAH </cmt>
+  </rtept>
+  <rtept lat="-30.675867" lon="150.609033">
+    <name>START</name>
+    <cmt>BORAH </cmt>
+  </rtept>
+  <rtept lat="-30.729933" lon="150.649200">
+    <name>TURN01</name>
+    <cmt>BALDWI</cmt>
+  </rtept>
+  <rtept lat="-30.763683" lon="150.723200">
+    <name>FINISH</name>
+    <cmt>MANAIR</cmt>
+  </rtept>
+  <rtept lat="-30.763683" lon="150.723200">
+    <name>LANDING</name>
+    <cmt>MANAIR</cmt>
+  </rtept>
+</rte>
 <trk>
   <name>GNSSALTTRK</name>
   <desc>IGCHDRS~HFPLTPILOT:CHRIS JONES~</desc>
@@ -133,7 +157,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/
 <trkpt lat="-30.678450" lon="150.606117">
 <time>2004-04-24T04:20:44Z</time>
 </trkpt>
-<trkpt lat="-30.677967" lon="150.607050">
+<trkpt lat="-30.677983" lon="150.607050">
 <time>2004-04-24T04:21:14Z</time>
 </trkpt>
 <trkpt lat="-30.677633" lon="150.606900">
@@ -351,28 +375,4 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/
 </trkpt>
 </trkseg>
 </trk>
-<rte>
-  <name>0001</name>
-  <desc>IGCDATE000000: </desc>
-  <rtept lat="-30.675867" lon="150.609033">
-    <name>TAKEOFF</name>
-    <cmt>BORAH </cmt>
-  </rtept>
-  <rtept lat="-30.675867" lon="150.609033">
-    <name>START</name>
-    <cmt>BORAH </cmt>
-  </rtept>
-  <rtept lat="-30.729933" lon="150.649200">
-    <name>TURN01</name>
-    <cmt>BALDWI</cmt>
-  </rtept>
-  <rtept lat="-30.763683" lon="150.723200">
-    <name>FINISH</name>
-    <cmt>MANAIR</cmt>
-  </rtept>
-  <rtept lat="-30.763683" lon="150.723200">
-    <name>LANDING</name>
-    <cmt>MANAIR</cmt>
-  </rtept>
-</rte>
 </gpx>
index beb86d8e28ac6cfdcd2e76dd9d20f841086e4a09..9d3c0071eab306f647bb946bf7bb2785a23b26db 100644 (file)
@@ -48,7 +48,7 @@ B0419123040526S15036253EA0000000000
 B0419433040646S15036334EA0000000000\r
 B0420133040794S15036367EA0000000000\r
 B0420443040707S15036367EA0000000000\r
-B0421143040678S15036423EA0000000000\r
+B0421143040679S15036423EA0000000000\r
 B0421443040658S15036414EA0000000000\r
 B0422153040772S15036358EA0000000000\r
 B0422453040722S15036423EA0000000000\r
index 6b2e340876814e37c3ca7b08d39a6a27fa0a17de..d841eac8e3d5265d6a03cdcb36b9d7dd7d4bbeff 100644 (file)
@@ -6,44 +6,78 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.topografix.com/GPX/1/0"
 xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
 <time>1970-01-01T00:00:00Z</time>
+<rte>
+  <name>0001</name>
+  <desc>IGCDATE160701: 500KTri</desc>
+  <rtept lat="51.189317" lon="-1.031650">
+<time>2001-07-15T21:38:41Z</time>
+    <name>TAKEOFF</name>
+    <cmt>LashamClubhouse</cmt>
+  </rtept>
+  <rtept lat="51.169650" lon="-1.044067">
+<time>2001-07-15T21:38:41Z</time>
+    <name>START</name>
+    <cmt>LashamStart S Start</cmt>
+  </rtept>
+  <rtept lat="52.151533" lon="-2.920450">
+<time>2001-07-15T21:38:41Z</time>
+    <name>TURN01</name>
+    <cmt>Sarnesfield TP1</cmt>
+  </rtept>
+  <rtept lat="52.502450" lon="-0.293533">
+<time>2001-07-15T21:38:41Z</time>
+    <name>TURN02</name>
+    <cmt>NormanCross TP2</cmt>
+  </rtept>
+  <rtept lat="51.169650" lon="-1.044067">
+<time>2001-07-15T21:38:41Z</time>
+    <name>FINISH</name>
+    <cmt>LashamStart S Finish</cmt>
+  </rtept>
+  <rtept lat="51.189317" lon="-1.031650">
+<time>2001-07-15T21:38:41Z</time>
+    <name>LANDING</name>
+    <cmt>LashamClubhouse</cmt>
+  </rtept>
+</rte>
 <trk>
   <name>PRESALTTRK</name>
   <desc>IGCHDRS~HFFXA035~HFPLTPILOT:Bill Bloggs~HFGTYGLIDERTYPE:Schleicher ASH-25~HFGIDGLIDERID:ABCD-1234~HFDTM100GPSDATUM:WGS-1984~HFRFWFIRMWAREVERSION:6.4~HFRHWHARDWAREVERSION:3.0~HFFTYFRTYPE:Manufacturer Model~HFGPSMarconiCanada:Superstar 12ch max10000m~HFPRSPRESSALTSENSOR:Sensyn XYZ1111 max11000m~HFCIDCOMPETITIONID:XYZ-78910~HFCCLCOMPETITIONCLASS:15mMotor Glider~HFSCMSECONDCREW:JohnSmith~</desc>
 <trkseg>
 <trkpt lat="54.118683" lon="-2.822367">
-<ele>280.000000</ele>
+  <ele>280.000000</ele>
 <time>2001-07-16T16:02:40Z</time>
 </trkpt>
 <trkpt lat="51.118767" lon="-1.821667">
-<ele>288.000000</ele>
+  <ele>288.000000</ele>
 <time>2001-07-16T16:02:45Z</time>
 </trkpt>
 <trkpt lat="51.118900" lon="-1.821383">
-<ele>290.000000</ele>
+  <ele>290.000000</ele>
 <time>2001-07-16T16:02:50Z</time>
 </trkpt>
 <trkpt lat="51.119000" lon="-1.820350">
-<ele>290.000000</ele>
+  <ele>290.000000</ele>
 <time>2001-07-16T16:02:55Z</time>
 </trkpt>
 <trkpt lat="51.119167" lon="-1.820033">
-<ele>291.000000</ele>
+  <ele>291.000000</ele>
 <time>2001-07-16T16:03:00Z</time>
 </trkpt>
 <trkpt lat="51.119667" lon="-1.819750">
-<ele>291.000000</ele>
+  <ele>291.000000</ele>
 <time>2001-07-16T16:03:05Z</time>
 </trkpt>
 <trkpt lat="51.120200" lon="-1.819567">
-<ele>293.000000</ele>
+  <ele>293.000000</ele>
 <time>2001-07-16T16:03:10Z</time>
 </trkpt>
 <trkpt lat="51.120333" lon="-1.819167">
-<ele>494.000000</ele>
+  <ele>494.000000</ele>
 <time>2001-07-17T16:02:48Z</time>
 </trkpt>
 <trkpt lat="51.122167" lon="-1.818783">
-<ele>496.000000</ele>
+  <ele>496.000000</ele>
 <time>2001-07-17T16:02:52Z</time>
 </trkpt>
 </trkseg>
@@ -53,75 +87,41 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/
   <desc>IGCHDRS~HFFXA035~HFPLTPILOT:Bill Bloggs~HFGTYGLIDERTYPE:Schleicher ASH-25~HFGIDGLIDERID:ABCD-1234~HFDTM100GPSDATUM:WGS-1984~HFRFWFIRMWAREVERSION:6.4~HFRHWHARDWAREVERSION:3.0~HFFTYFRTYPE:Manufacturer Model~HFGPSMarconiCanada:Superstar 12ch max10000m~HFPRSPRESSALTSENSOR:Sensyn XYZ1111 max11000m~HFCIDCOMPETITIONID:XYZ-78910~HFCCLCOMPETITIONCLASS:15mMotor Glider~HFSCMSECONDCREW:JohnSmith~</desc>
 <trkseg>
 <trkpt lat="54.118683" lon="-2.822367">
-<ele>421.000000</ele>
+  <ele>421.000000</ele>
 <time>2001-07-16T16:02:40Z</time>
 </trkpt>
 <trkpt lat="51.118767" lon="-1.821667">
-<ele>429.000000</ele>
+  <ele>429.000000</ele>
 <time>2001-07-16T16:02:45Z</time>
 </trkpt>
 <trkpt lat="51.118900" lon="-1.821383">
-<ele>432.000000</ele>
+  <ele>432.000000</ele>
 <time>2001-07-16T16:02:50Z</time>
 </trkpt>
 <trkpt lat="51.119000" lon="-1.820350">
-<ele>430.000000</ele>
+  <ele>430.000000</ele>
 <time>2001-07-16T16:02:55Z</time>
 </trkpt>
 <trkpt lat="51.119167" lon="-1.820033">
-<ele>432.000000</ele>
+  <ele>432.000000</ele>
 <time>2001-07-16T16:03:00Z</time>
 </trkpt>
 <trkpt lat="51.119667" lon="-1.819750">
-<ele>435.000000</ele>
+  <ele>435.000000</ele>
 <time>2001-07-16T16:03:05Z</time>
 </trkpt>
 <trkpt lat="51.120200" lon="-1.819567">
-<ele>435.000000</ele>
+  <ele>435.000000</ele>
 <time>2001-07-16T16:03:10Z</time>
 </trkpt>
 <trkpt lat="51.120333" lon="-1.819167">
-<ele>436.000000</ele>
+  <ele>436.000000</ele>
 <time>2001-07-17T16:02:48Z</time>
 </trkpt>
 <trkpt lat="51.122167" lon="-1.818783">
-<ele>439.000000</ele>
+  <ele>439.000000</ele>
 <time>2001-07-17T16:02:52Z</time>
 </trkpt>
 </trkseg>
 </trk>
-<rte>
-  <name>0001</name>
-  <desc>IGCDATE160701: 500KTri</desc>
-  <rtept lat="51.189317" lon="-1.031650">
-<time>2001-07-15T21:38:41Z</time>
-    <name>TAKEOFF</name>
-    <cmt>LashamClubhouse</cmt>
-  </rtept>
-  <rtept lat="51.169650" lon="-1.044067">
-<time>2001-07-15T21:38:41Z</time>
-    <name>START</name>
-    <cmt>LashamStart S Start</cmt>
-  </rtept>
-  <rtept lat="52.151533" lon="-2.920450">
-<time>2001-07-15T21:38:41Z</time>
-    <name>TURN01</name>
-    <cmt>Sarnesfield TP1</cmt>
-  </rtept>
-  <rtept lat="52.502450" lon="-0.293533">
-<time>2001-07-15T21:38:41Z</time>
-    <name>TURN02</name>
-    <cmt>NormanCross TP2</cmt>
-  </rtept>
-  <rtept lat="51.169650" lon="-1.044067">
-<time>2001-07-15T21:38:41Z</time>
-    <name>FINISH</name>
-    <cmt>LashamStart S Finish</cmt>
-  </rtept>
-  <rtept lat="51.189317" lon="-1.031650">
-<time>2001-07-15T21:38:41Z</time>
-    <name>LANDING</name>
-    <cmt>LashamClubhouse</cmt>
-  </rtept>
-</rte>
 </gpx>
diff --git a/reference/lowrance.usr b/reference/lowrance.usr
new file mode 100644 (file)
index 0000000..1982f8a
Binary files /dev/null and b/reference/lowrance.usr differ
diff --git a/reference/ov2-arc-out.ref b/reference/ov2-arc-out.ref
new file mode 100644 (file)
index 0000000..11d8ddd
Binary files /dev/null and b/reference/ov2-arc-out.ref differ
diff --git a/reference/ov2-geo-out.ref b/reference/ov2-geo-out.ref
new file mode 100644 (file)
index 0000000..95d3bb5
Binary files /dev/null and b/reference/ov2-geo-out.ref differ
diff --git a/reference/ov2-in.ref b/reference/ov2-in.ref
new file mode 100644 (file)
index 0000000..4c0e75d
--- /dev/null
@@ -0,0 +1,9 @@
+Mountain Bike Heaven by susy1313 3558.322N 08708.081W 0000000m Mountain Bike Heaven by susy13 a
+The Troll by a182pilot & Family 3605.441N 08640.772W 0000000m The Troll by a182pilot & Famil a
+Dive Bomber by JoGPS & family 3559.776N 08637.207W 0000000m Dive Bomber by JoGPS & family  a
+FOSTER by JoGPS & Family 3602.309N 08638.917W 0000000m FOSTER by JoGPS & Family       a
+Logan Lighthouse by JoGps & Family 3606.731N 08644.506W 0000000m Logan Lighthouse by JoGps & Fa a
+Ganier Cache by Susy1313 3603.845N 08647.431W 0000000m Ganier Cache by Susy1313       a
+Shy's Hill by FireFighterEng33 3605.266N 08648.583W 0000000m Shy's Hill by FireFighterEng33 a
+GittyUp by JoGPS / Warner Parks 3603.450N 08653.519W 0000000m GittyUp by JoGPS / Warner Park a
+Inlighting by JoGPS / Warner Parks 3604.968N 08652.036W 0000000m Inlighting by JoGPS / Warner P a
diff --git a/reference/pathaway-geo.loc b/reference/pathaway-geo.loc
new file mode 100644 (file)
index 0000000..8e7a019
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0"?><loc version="1.0" src="EasyGPS">
+<waypoint>
+<name id="GCEBB"><![CDATA[Mountain Bike Heaven by susy1313]]></name>
+<coord lat="35.972033" lon="-87.134700"/>
+</waypoint>
+<waypoint>
+<name id="GC1A37"><![CDATA[The Troll by a182pilot & Family]]></name>
+<coord lat="36.090683" lon="-86.679550"/>
+</waypoint>
+<waypoint>
+<name id="GC1C2B"><![CDATA[Dive Bomber by JoGPS & family]]></name>
+<coord lat="35.996267" lon="-86.620117"/>
+</waypoint>
+<waypoint>
+<name id="GC25A9"><![CDATA[FOSTER by JoGPS & Family]]></name>
+<coord lat="36.038483" lon="-86.648617"/>
+</waypoint>
+<waypoint>
+<name id="GC2723"><![CDATA[Logan Lighthouse by JoGps & Family]]></name>
+<coord lat="36.112183" lon="-86.741767"/>
+</waypoint>
+<waypoint>
+<name id="GC2B71"><![CDATA[Ganier Cache by Susy1313]]></name>
+<coord lat="36.064083" lon="-86.790517"/>
+</waypoint>
+<waypoint>
+<name id="GC309F"><![CDATA[Shy's Hill by FireFighterEng33]]></name>
+<coord lat="36.087767" lon="-86.809733"/>
+</waypoint>
+<waypoint>
+<name id="GC317A"><![CDATA[GittyUp by JoGPS / Warner Parks]]></name>
+<coord lat="36.057500" lon="-86.892000"/>
+</waypoint>
+<waypoint>
+<name id="GC317D"><![CDATA[Inlighting by JoGPS / Warner Parks]]></name>
+<coord lat="36.082800" lon="-86.867283"/>
+</waypoint>
+</loc>
index b8d58a158ac7237cf8744c0a083a291c5ecc4ebc..8030ff5297c839991fdf9e4e1c8831bf818853cb 100644 (file)
@@ -57,7 +57,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/
 <rte>
 <name>ATCHAFALAYA</name>
 <desc>ROUTE1</desc>
-<number>1</number>
+<number>2</number>
 <rtept lat="30.280517" lon="-91.685883">
 <ele>0.000000</ele>
 <name><![CDATA[ATLAUN]]></name>
diff --git a/reference/route/tef_xml.mps b/reference/route/tef_xml.mps
new file mode 100644 (file)
index 0000000..3021af6
Binary files /dev/null and b/reference/route/tef_xml.mps differ
diff --git a/reference/route/tef_xml.sample.xml b/reference/route/tef_xml.sample.xml
new file mode 100644 (file)
index 0000000..ddb466e
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<TEF Comment="TourExchangeFormat" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Header Version="1.5" Datasource="RoutePlanningProgramm" Name="von bei D 95030 Hof/Innenstadt nach bei D95032 Hof " Software="MOTORRAD Tourenplaner 2005/2006 9.50" CreationTime="2005-05-05T20:40:31"><Setup CoordinateSystem="GeoDecimal" Axissystem="Math" Measure="metric"/><Route Distance="417812000" Duration="34238"/></Header><WaypointList ItemCount="262"><Item PointDist="0" PointDescription="bei D 95030 Hof/Innenstadt " Turn="sa" SegDescription="B2 Schleizer Strasse" SegDist="4320" SegTime="306" TimeStamp="2005-05-05T20:36:32" Prio="0"><Point x="11,91293" y="50,32684"/></Item><Item PointDist="4320" PointDescription="in Zedtwitz halb rechts halten auf B2 Hofer Strasse" Turn="hr" SegDescription="B2 Hofer Strasse" SegDist="2120" SegTime="147" TimeStamp="2005-05-05T20:41:38" Prio="0"><Point x="11,90373" y="50,36235"/></Item><Item PointDist="6440" PointDescription="rechts abbiegen auf B2" Turn="r" SegDescription="B2" SegDist="3078" SegTime="256" TimeStamp="2005-05-05T20:44:05" Prio="0"><Point x="11,8914" y="50,37236"/></Item><Item PointDist="9518" PointDescription="bei D 95183 Töpen " Turn="sa" SegDescription="B2\Hofer Strasse" SegDist="6492" SegTime="398" TimeStamp="2005-05-05T20:48:21" ViaStation="true" Prio="0"><Point x="11,86756" y="50,39372"/></Item><Item PointDist="16010" PointDescription="in Gefell links abbiegen auf B90 Friedensstrasse" Turn="l" SegDescription="B90 Friedensstrasse" SegDist="16810" SegTime="1064" TimeStamp="2005-05-05T20:54:59" Prio="0"><Point x="11,86064" y="50,44219"/></Item><Item PointDist="32820" PointDescription="in Lobenstein halb rechts halten auf B90 Hirschberger Strasse" Turn="hr" SegDescription="B90 Hirschberger Strasse" SegDist="690" SegTime="134" TimeStamp="2005-05-05T21:12:43" Prio="0"><Point x="11,65216" y="50,45091"/></Item><Item PointDist="33510" PointDescription="geradeaus weiter auf Strasse der Jugend (L1095)" Turn="sa" SegDescription="Strasse der Jugend (L1095)" SegDist="703" SegTime="16" TimeStamp="2005-05-05T21:14:57" Prio="0"><Point x="11,64293" y="50,45152"/></Item><Item PointDist="34213" PointDescription="bei D 07356 Lobenstein " Turn="sa" SegDescription="L1095\Strasse der Jugend" SegDist="724" SegTime="111" TimeStamp="2005-05-05T21:15:13" ViaStation="true" Prio="0"><Point x="11,64281" y="50,45756"/></Item><Item PointDist="34937" PointDescription="links abbiegen auf L1099" Turn="l" SegDescription="L1099" SegDist="1220" SegTime="67" TimeStamp="2005-05-05T21:17:04" Prio="0"><Point x="11,64815" y="50,46225"/></Item><Item PointDist="36157" PointDescription="rechts abbiegen" Turn="r" SegDist="900" SegTime="20" TimeStamp="2005-05-05T21:18:11" Prio="0"><Point x="11,64099" y="50,47227"/></Item><Item PointDist="37057" PointDescription="in Schönbrunn links abbiegen auf Schönbrunn" Turn="l" SegDescription="Schönbrunn" SegDist="60" SegTime="20" TimeStamp="2005-05-05T21:18:31" Prio="0"><Point x="11,65227" y="50,47546"/></Item><Item PointDist="37117" PointDescription="links abbiegen auf Schönbrunn" Turn="l" SegDescription="Schönbrunn" SegDist="110" SegTime="13" TimeStamp="2005-05-05T21:18:51" Prio="0"><Point x="11,65289" y="50,47575"/></Item><Item PointDist="37227" PointDescription="halb rechts halten auf Schönbrunn" Turn="hr" SegDescription="Schönbrunn" SegDist="70" SegTime="66" TimeStamp="2005-05-05T21:19:04" Prio="0"><Point x="11,65293" y="50,47667"/></Item><Item PointDist="37297" PointDescription="geradeaus weiter auf L1095 " Turn="sa" SegDescription="L1095 " SegDist="730" SegTime="5" TimeStamp="2005-05-05T21:20:10" Prio="0"><Point x="11,65362" y="50,47711"/></Item><Item PointDist="38027" PointDescription="halb links halten auf L1095 " Turn="hl" SegDescription="L1095 " SegDist="60" SegTime="5" TimeStamp="2005-05-05T21:20:15" Prio="0"><Point x="11,661" y="50,4808"/></Item><Item PointDist="38087" PointDescription="in Bellevue links abbiegen auf L1095" Turn="l" SegDescription="L1095" SegDist="7740" SegTime="610" TimeStamp="2005-05-05T21:20:20" Prio="0"><Point x="11,66163" y="50,48106"/></Item><Item PointDist="45827" PointDescription="in Saalburg geradeaus weiter auf L1095" Turn="sa" SegDescription="L1095" SegDist="80" SegTime="5" TimeStamp="2005-05-05T21:30:30" Prio="0"><Point x="11,72845" y="50,49956"/></Item><Item PointDist="45907" PointDescription="geradeaus weiter auf L1095" Turn="sa" SegDescription="L1095" SegDist="480" SegTime="64" TimeStamp="2005-05-05T21:30:35" Prio="0"><Point x="11,7291" y="50,50013"/></Item><Item PointDist="46387" PointDescription="links abbiegen auf L1095" Turn="l" SegDescription="L1095" SegDist="90" SegTime="17" TimeStamp="2005-05-05T21:31:39" Prio="0"><Point x="11,7341" y="50,50281"/></Item><Item PointDist="46477" PointDescription="rechts abbiegen auf Schleizer Strasse (L1095)" Turn="r" SegDescription="Schleizer Strasse (L1095)" SegDist="430" SegTime="81" TimeStamp="2005-05-05T21:31:56" Prio="0"><Point x="11,7334" y="50,50348"/></Item><Item PointDist="46907" PointDescription="bei D 07929 Saalburg-Ebersdorf/Saalburg " Turn="sa" SegDescription="L1095" SegDist="2011" SegTime="139" TimeStamp="2005-05-05T21:33:17" ViaStation="true" Prio="0"><Point x="11,73346" y="50,50719"/></Item><Item PointDist="48918" PointDescription="geradeaus weiter auf L1095" Turn="sa" SegDescription="L1095" SegDist="850" SegTime="88" TimeStamp="2005-05-05T21:35:36" Prio="0"><Point x="11,73867" y="50,52311"/></Item><Item PointDist="49768" PointDescription="links abbiegen" Turn="l" SegDist="2862" SegTime="224" TimeStamp="2005-05-05T21:37:04" Prio="0"><Point x="11,74796" y="50,52771"/></Item><Item PointDist="52630" PointDescription="bei D07907 Burgk/Burgkhammer " Turn="sa" SegDescription="K550" SegDist="2022" SegTime="122" TimeStamp="2005-05-05T21:40:48" ViaStation="true" Prio="0"><Point x="11,71402" y="50,52467"/></Item><Item PointDist="54652" PointDescription="rechts abbiegen auf L1101" Turn="r" SegDescription="L1101" SegDist="2200" SegTime="175" TimeStamp="2005-05-05T21:42:50" Prio="0"><Point x="11,70781" y="50,54068"/></Item><Item PointDist="56852" PointDescription="geradeaus weiter auf Burgkhammer " Turn="sa" SegDescription="Burgkhammer " SegDist="982" SegTime="16" TimeStamp="2005-05-05T21:45:45" Prio="0"><Point x="11,72492" y="50,54671"/></Item><Item PointDist="57834" PointDescription="bei D 07907 Burgk/Burgkhammer " Turn="sa" SegDescription="Burgkhammer" SegDist="22" SegTime="14" TimeStamp="2005-05-05T21:46:01" ViaStation="true" Prio="0"><Point x="11,71945" y="50,55144"/></Item><Item PointDist="57856" PointDescription="in Burgkhammer links abbiegen auf L1101 " Turn="l" SegDescription="L1101 " SegDist="3160" SegTime="219" TimeStamp="2005-05-05T21:46:15" Prio="0"><Point x="11,71946" y="50,55163"/></Item><Item PointDist="61016" PointDescription="links abbiegen" Turn="l" SegDist="4880" SegTime="348" TimeStamp="2005-05-05T21:49:54" Prio="0"><Point x="11,70781" y="50,54068"/></Item><Item PointDist="65896" PointDescription="links abbiegen auf L1095" Turn="l" SegDescription="L1095" SegDist="2520" SegTime="217" TimeStamp="2005-05-05T21:55:42" Prio="0"><Point x="11,74796" y="50,52771"/></Item><Item PointDist="68416" PointDescription="links abbiegen auf Burgker Chaussee (L1101)" Turn="l" SegDescription="Burgker Chaussee (L1101)" SegDist="3520" SegTime="258" TimeStamp="2005-05-05T21:59:19" Prio="0"><Point x="11,77272" y="50,54302"/></Item><Item PointDist="71936" PointDescription="links abbiegen auf Burgker Strasse (L1101)" Turn="l" SegDescription="Burgker Strasse (L1101)" SegDist="40" SegTime="108" TimeStamp="2005-05-05T22:03:37" Prio="0"><Point x="11,73423" y="50,55532"/></Item><Item PointDist="71976" PointDescription="halb rechts halten auf L2357" Turn="hr" SegDescription="L2357" SegDist="1195" SegTime="108" TimeStamp="2005-05-05T22:05:25" Prio="0"><Point x="11,73389" y="50,555"/></Item><Item PointDist="73171" PointDescription="bei D 07907 Burgk " Turn="sa" SegDescription="L2357" SegDist="1195" SegTime="4" TimeStamp="2005-05-05T22:07:13" ViaStation="true" Prio="0"><Point x="11,71981" y="50,55627"/></Item><Item PointDist="74366" PointDescription="geradeaus weiter auf Burgker Strasse (L1101)" Turn="sa" SegDescription="Burgker Strasse (L1101)" SegDist="40" SegTime="34" TimeStamp="2005-05-05T22:07:17" Prio="0"><Point x="11,73389" y="50,555"/></Item><Item PointDist="74406" PointDescription="geradeaus weiter auf L2357" Turn="sa" SegDescription="L2357" SegDist="424" SegTime="16" TimeStamp="2005-05-05T22:07:51" Prio="0"><Point x="11,73423" y="50,55532"/></Item><Item PointDist="74830" PointDescription="bei D 07907 Schleiz/Möschlitz " Turn="sa" SegDescription="L2357" SegDist="198" SegTime="99" TimeStamp="2005-05-05T22:08:07" ViaStation="true" Prio="0"><Point x="11,73688" y="50,55874"/></Item><Item PointDist="75028" PointDescription="links abbiegen" Turn="l" SegDist="1660" SegTime="55" TimeStamp="2005-05-05T22:09:46" Prio="0"><Point x="11,73818" y="50,56032"/></Item><Item PointDist="76688" PointDescription="in Grochwitz halb rechts halten auf Mühlenstrasse" Turn="hr" SegDescription="Mühlenstrasse" SegDist="110" SegTime="27" TimeStamp="2005-05-05T22:10:41" Prio="0"><Point x="11,72963" y="50,57023"/></Item><Item PointDist="76798" PointDescription="geradeaus weiter auf Sackgasse" Turn="sa" SegDescription="Sackgasse" SegDist="210" SegTime="158" TimeStamp="2005-05-05T22:11:08" Prio="0"><Point x="11,73022" y="50,57114"/></Item><Item PointDist="77008" PointDescription="geradeaus weiter " Turn="sa" SegDist="1670" SegTime="118" TimeStamp="2005-05-05T22:13:46" Prio="0"><Point x="11,7323" y="50,57225"/></Item><Item PointDist="78678" PointDescription="links abbiegen auf L1103 " Turn="l" SegDescription="L1103 " SegDist="1310" SegTime="2" TimeStamp="2005-05-05T22:15:44" Prio="0"><Point x="11,75048" y="50,57964"/></Item><Item PointDist="79988" PointDescription="links abbiegen auf L1103" Turn="l" SegDescription="L1103" SegDist="670" SegTime="68" TimeStamp="2005-05-05T22:15:46" Prio="0"><Point x="11,74212" y="50,58952"/></Item><Item PointDist="80658" PointDescription="in Crispendorf halb rechts halten auf Ortsstrasse (L1103)" Turn="hr" SegDescription="Ortsstrasse (L1103)" SegDist="410" SegTime="42" TimeStamp="2005-05-05T22:16:54" Prio="0"><Point x="11,73445" y="50,59219"/></Item><Item PointDist="81068" PointDescription="halb rechts halten auf Ortsstrasse (L1103)" Turn="hr" SegDescription="Ortsstrasse (L1103)" SegDist="1420" SegTime="187" TimeStamp="2005-05-05T22:17:36" Prio="0"><Point x="11,72976" y="50,59057"/></Item><Item PointDist="82488" PointDescription="halb rechts halten auf L1103" Turn="hr" SegDescription="L1103" SegDist="6140" SegTime="453" TimeStamp="2005-05-05T22:20:43" Prio="0"><Point x="11,71203" y="50,59226"/></Item><Item PointDist="88628" PointDescription="in Ziegenrück halb links halten auf Schleizer Strasse (L1103)" Turn="hl" SegDescription="Schleizer Strasse (L1103)" SegDist="430" SegTime="64" TimeStamp="2005-05-05T22:28:16" Prio="0"><Point x="11,651" y="50,60566"/></Item><Item PointDist="89058" PointDescription="rechts abbiegen auf Plothental (L2350)" Turn="r" SegDescription="Plothental (L2350)" SegDist="277" SegTime="59" TimeStamp="2005-05-05T22:29:20" Prio="0"><Point x="11,6498" y="50,60874"/></Item><Item PointDist="89335" PointDescription="bei D 07924 Ziegenrück " Turn="sa" SegDescription="L2350\Plothental" SegDist="4072" SegTime="367" TimeStamp="2005-05-05T22:30:19" ViaStation="true" Prio="0"><Point x="11,65335" y="50,60809"/></Item><Item PointDist="93407" PointDescription="in Tausa halb links halten auf Tausa (L2350)" Turn="hl" SegDescription="Tausa (L2350)" SegDist="1440" SegTime="217" TimeStamp="2005-05-05T22:36:26" Prio="0"><Point x="11,69355" y="50,62715"/></Item><Item PointDist="94847" PointDescription="in Bucha links abbiegen auf Ortsstrasse (L2350)" Turn="l" SegDescription="Ortsstrasse (L2350)" SegDist="1500" SegTime="220" TimeStamp="2005-05-05T22:40:03" Prio="0"><Point x="11,70687" y="50,63505"/></Item><Item PointDist="96347" PointDescription="rechts abbiegen auf L2350" Turn="r" SegDescription="L2350" SegDist="1790" SegTime="143" TimeStamp="2005-05-05T22:43:43" Prio="0"><Point x="11,70356" y="50,64738"/></Item><Item PointDist="98137" PointDescription="in Knau halb links halten auf Hauptstrasse (L2349)" Turn="hl" SegDescription="Hauptstrasse (L2349)" SegDist="284" SegTime="54" TimeStamp="2005-05-05T22:46:06" Prio="0"><Point x="11,71955" y="50,65222"/></Item><Item PointDist="98421" PointDescription="bei D 07389 Knau " Turn="sa" SegDescription="L2349\Hauptstrasse" SegDist="269" SegTime="445" TimeStamp="2005-05-05T22:47:00" ViaStation="true" Prio="0"><Point x="11,72288" y="50,65084"/></Item><Item PointDist="98690" PointDescription="links abbiegen auf Hauptstrasse (L2349)" Turn="l" SegDescription="Hauptstrasse (L2349)" SegDist="4426" SegTime="145" TimeStamp="2005-05-05T22:54:25" Prio="0"><Point x="11,7256" y="50,64925"/></Item><Item PointDist="103116" PointDescription="bei D 07907 Plothen " Turn="sa" SegDescription="L2349\Ortsstrasse" SegDist="3689" SegTime="332" TimeStamp="2005-05-05T22:56:50" ViaStation="true" Prio="0"><Point x="11,77321" y="50,63884"/></Item><Item PointDist="106805" PointDescription="in Dittersdorf rechts abbiegen auf L1077" Turn="r" SegDescription="L1077" SegDist="3880" SegTime="274" TimeStamp="2005-05-05T23:02:22" Prio="0"><Point x="11,81631" y="50,6435"/></Item><Item PointDist="110685" PointDescription="rechts abbiegen auf Ziegelei" Turn="r" SegDescription="Ziegelei" SegDist="100" SegTime="41" TimeStamp="2005-05-05T23:06:56" Prio="0"><Point x="11,82502" y="50,61031"/></Item><Item PointDist="110785" PointDescription="halb rechts halten auf B2" Turn="hr" SegDescription="B2" SegDist="690" SegTime="8" TimeStamp="2005-05-05T23:07:37" Prio="0"><Point x="11,82507" y="50,60955"/></Item><Item PointDist="111475" PointDescription="in Oettersdorf links abbiegen auf Löhmaer Weg  (K301)" Turn="l" SegDescription="Löhmaer Weg  (K301)" SegDist="180" SegTime="31" TimeStamp="2005-05-05T23:07:45" Prio="0"><Point x="11,82391" y="50,60362"/></Item><Item PointDist="111655" PointDescription="rechts abbiegen auf Löhmaer Weg  (K301)" Turn="r" SegDescription="Löhmaer Weg  (K301)" SegDist="260" SegTime="7" TimeStamp="2005-05-05T23:08:16" Prio="0"><Point x="11,82582" y="50,60472"/></Item><Item PointDist="111915" PointDescription="links abbiegen auf Löhmaer Weg (K301)" Turn="l" SegDescription="Löhmaer Weg (K301)" SegDist="2050" SegTime="172" TimeStamp="2005-05-05T23:08:23" Prio="0"><Point x="11,8281" y="50,60284"/></Item><Item PointDist="113965" PointDescription="rechts abbiegen" Turn="r" SegDist="330" SegTime="19" TimeStamp="2005-05-05T23:11:15" Prio="0"><Point x="11,84991" y="50,6143"/></Item><Item PointDist="114295" PointDescription="in Löhma links abbiegen auf Ortsstrasse" Turn="l" SegDescription="Ortsstrasse" SegDist="210" SegTime="63" TimeStamp="2005-05-05T23:11:34" Prio="0"><Point x="11,85166" y="50,61166"/></Item><Item PointDist="114505" PointDescription="geradeaus weiter " Turn="sa" SegDist="2300" SegTime="188" TimeStamp="2005-05-05T23:12:37" Prio="0"><Point x="11,85462" y="50,61161"/></Item><Item PointDist="116805" PointDescription="in Kirschkau geradeaus weiter auf Ortsstrasse" Turn="sa" SegDescription="Ortsstrasse" SegDist="260" SegTime="49" TimeStamp="2005-05-05T23:15:45" Prio="0"><Point x="11,88309" y="50,60609"/></Item><Item PointDist="117065" PointDescription="rechts abbiegen auf Ortsstrasse" Turn="r" SegDescription="Ortsstrasse" SegDist="70" SegTime="20" TimeStamp="2005-05-05T23:16:34" Prio="0"><Point x="11,88594" y="50,60469"/></Item><Item PointDist="117135" PointDescription="rechts abbiegen auf Ortsstrasse" Turn="r" SegDescription="Ortsstrasse" SegDist="110" SegTime="13" TimeStamp="2005-05-05T23:16:54" Prio="0"><Point x="11,88574" y="50,60413"/></Item><Item PointDist="117245" PointDescription="links abbiegen auf Ortsstrasse" Turn="l" SegDescription="Ortsstrasse" SegDist="70" SegTime="9" TimeStamp="2005-05-05T23:17:07" Prio="0"><Point x="11,88462" y="50,60354"/></Item><Item PointDist="117315" PointDescription="rechts abbiegen auf Ortsstrasse" Turn="r" SegDescription="Ortsstrasse" SegDist="50" SegTime="56" TimeStamp="2005-05-05T23:17:16" Prio="0"><Point x="11,88556" y="50,60331"/></Item><Item PointDist="117365" PointDescription="geradeaus weiter auf B94 " Turn="sa" SegDescription="B94 " SegDist="1040" SegTime="95" TimeStamp="2005-05-05T23:18:12" Prio="0"><Point x="11,88541" y="50,60292"/></Item><Item PointDist="118405" PointDescription="rechts abbiegen auf B94" Turn="r" SegDescription="B94" SegDist="480" SegTime="49" TimeStamp="2005-05-05T23:19:47" Prio="0"><Point x="11,88776" y="50,59435"/></Item><Item PointDist="118885" PointDescription="links abbiegen auf Dorfstrasse" Turn="l" SegDescription="Dorfstrasse" SegDist="340" SegTime="19" TimeStamp="2005-05-05T23:20:36" Prio="0"><Point x="11,88475" y="50,59056"/></Item><Item PointDist="119225" PointDescription="in Lössau links abbiegen" Turn="l" SegDist="3000" SegTime="241" TimeStamp="2005-05-05T23:20:55" Prio="0"><Point x="11,88621" y="50,5878"/></Item><Item PointDist="122225" PointDescription="bei D 07907 Schleiz/Langenbuch " Turn="sa" SegDescription="K304\Lössauer Strasse" SegDist="153" SegTime="12" TimeStamp="2005-05-05T23:24:56" ViaStation="true" Prio="0"><Point x="11,90733" y="50,56821"/></Item><Item PointDist="122378" PointDescription="in Langenbuch links abbiegen auf Thierbacher Strasse (L2348)" Turn="l" SegDescription="Thierbacher Strasse (L2348)" SegDist="1940" SegTime="211" TimeStamp="2005-05-05T23:25:08" Prio="0"><Point x="11,90787" y="50,56691"/></Item><Item PointDist="124318" PointDescription="geradeaus weiter" Turn="sa" SegDist="4940" SegTime="456" TimeStamp="2005-05-05T23:28:39" Prio="0"><Point x="11,93059" y="50,57547"/></Item><Item PointDist="129258" PointDescription="in Pausa/Vogtl. rechts abbiegen" Turn="r" SegDist="230" SegTime="28" TimeStamp="2005-05-05T23:36:15" Prio="0"><Point x="11,99148" y="50,58023"/></Item><Item PointDist="129488" PointDescription="rechts abbiegen auf Plauensche Strasse (S316)" Turn="r" SegDescription="Plauensche Strasse (S316)" SegDist="270" SegTime="21" TimeStamp="2005-05-05T23:36:43" Prio="0"><Point x="11,99249" y="50,5783"/></Item><Item PointDist="129758" PointDescription="in Oberreichenau halb links halten auf Am Mühlgraben (S316)" Turn="hl" SegDescription="Am Mühlgraben (S316)" SegDist="133" SegTime="9" TimeStamp="2005-05-05T23:37:04" Prio="0"><Point x="11,99057" y="50,57624"/></Item><Item PointDist="129891" PointDescription="bei D 07952 Pausa/Oberreichenau " Turn="sa" SegDescription="S316\Am Mühlgraben" SegDist="8503" SegTime="685" TimeStamp="2005-05-05T23:37:13" ViaStation="true" Prio="0"><Point x="11,99127" y="50,57521"/></Item><Item PointDist="138394" PointDescription="in Syrau halb rechts halten auf B282/E49 Hauptstrasse" Turn="hr" SegDescription="B282/E49 Hauptstrasse" SegDist="107" SegTime="15" TimeStamp="2005-05-05T23:48:38" Prio="0"><Point x="12,08104" y="50,54202"/></Item><Item PointDist="138501" PointDescription="bei D 08548 Syrau " Turn="sa" SegDescription="B282/E49\Hauptstrasse" SegDist="2884" SegTime="195" TimeStamp="2005-05-05T23:48:53" ViaStation="true" Prio="0"><Point x="12,08196" y="50,54133"/></Item><Item PointDist="141385" PointDescription="rechts abbiegen auf Pausaer Strasse" Turn="r" SegDescription="Pausaer Strasse" SegDist="1300" SegTime="107" TimeStamp="2005-05-05T23:52:08" Prio="0"><Point x="12,11052" y="50,5255"/></Item><Item PointDist="142685" PointDescription="rechts abbiegen auf B92/E49 Pausaer Strasse" Turn="r" SegDescription="B92/E49 Pausaer Strasse" SegDist="1340" SegTime="105" TimeStamp="2005-05-05T23:53:55" Prio="0"><Point x="12,12004" y="50,51718"/></Item><Item PointDist="144025" PointDescription="in Plauen links abbiegen auf Martin-Luther-Strasse" Turn="l" SegDescription="Martin-Luther-Strasse" SegDist="989" SegTime="71" TimeStamp="2005-05-05T23:55:40" Prio="0"><Point x="12,12962" y="50,50751"/></Item><Item PointDist="145014" PointDescription="bei D 08525 Plauen/Preißelpöhl " Turn="sa" SegDescription="Martin-Luther-Strasse" SegDist="339" SegTime="42" TimeStamp="2005-05-05T23:56:51" ViaStation="true" Prio="0"><Point x="12,14214" y="50,50466"/></Item><Item PointDist="145353" PointDescription="links abbiegen auf Lessingstrasse" Turn="l" SegDescription="Lessingstrasse" SegDist="510" SegTime="86" TimeStamp="2005-05-05T23:57:33" Prio="0"><Point x="12,14503" y="50,50233"/></Item><Item PointDist="145863" PointDescription="links abbiegen auf B173 Hammerstrasse" Turn="l" SegDescription="B173 Hammerstrasse" SegDist="3850" SegTime="318" TimeStamp="2005-05-05T23:58:59" Prio="0"><Point x="12,15144" y="50,50178"/></Item><Item PointDist="149713" PointDescription="links abbiegen auf Voigtsgrüner Weg (K6605)" Turn="l" SegDescription="Voigtsgrüner Weg (K6605)" SegDist="1370" SegTime="23" TimeStamp="2005-05-06T00:04:17" Prio="0"><Point x="12,18231" y="50,4977"/></Item><Item PointDist="151083" PointDescription="rechts abbiegen auf Zum Plom" Turn="r" SegDescription="Zum Plom" SegDist="1480" SegTime="146" TimeStamp="2005-05-06T00:04:40" Prio="0"><Point x="12,19489" y="50,50642"/></Item><Item PointDist="152563" PointDescription="rechts abbiegen" Turn="r" SegDist="650" SegTime="22" TimeStamp="2005-05-06T00:07:06" Prio="0"><Point x="12,21222" y="50,50799"/></Item><Item PointDist="153213" PointDescription="in Neuensalz links abbiegen auf B169" Turn="l" SegDescription="B169" SegDist="70" SegTime="10" TimeStamp="2005-05-06T00:07:28" Prio="0"><Point x="12,21867" y="50,50401"/></Item><Item PointDist="153283" PointDescription="links abbiegen auf B169 Alte Plauener Strasse" Turn="l" SegDescription="B169 Alte Plauener Strasse" SegDist="110" SegTime="4" TimeStamp="2005-05-06T00:07:38" Prio="0"><Point x="12,21954" y="50,50388"/></Item><Item PointDist="153393" PointDescription="geradeaus weiter auf B173 Hauptstrasse" Turn="sa" SegDescription="B173 Hauptstrasse" SegDist="511" SegTime="46" TimeStamp="2005-05-06T00:07:42" Prio="0"><Point x="12,22049" y="50,50457"/></Item><Item PointDist="153904" PointDescription="bei D 08541 Neuensalz " Turn="sa" SegDescription="B173\Hauptstrasse" SegDist="1889" SegTime="139" TimeStamp="2005-05-06T00:08:28" ViaStation="true" Prio="0"><Point x="12,22704" y="50,50632"/></Item><Item PointDist="155793" PointDescription="in Thossfell geradeaus weiter auf B173 Hauptstrasse" Turn="sa" SegDescription="B173 Hauptstrasse" SegDist="150" SegTime="22" TimeStamp="2005-05-06T00:10:47" Prio="0"><Point x="12,24283" y="50,51914"/></Item><Item PointDist="155943" PointDescription="geradeaus weiter auf B173 Hauptstrasse" Turn="sa" SegDescription="B173 Hauptstrasse" SegDist="460" SegTime="21" TimeStamp="2005-05-06T00:11:09" Prio="0"><Point x="12,24339" y="50,52043"/></Item><Item PointDist="156403" PointDescription="links abbiegen auf Gansgrüner Strasse (K7880)" Turn="l" SegDescription="Gansgrüner Strasse (K7880)" SegDist="20" SegTime="39" TimeStamp="2005-05-06T00:11:30" Prio="0"><Point x="12,24441" y="50,52453"/></Item><Item PointDist="156423" PointDescription="links abbiegen auf Gansgrüner Strasse (K7880)" Turn="l" SegDescription="Gansgrüner Strasse (K7880)" SegDist="1780" SegTime="126" TimeStamp="2005-05-06T00:12:09" Prio="0"><Point x="12,24423" y="50,52464"/></Item><Item PointDist="158203" PointDescription="in Gansgrün links abbiegen auf Dorfstrasse" Turn="l" SegDescription="Dorfstrasse" SegDist="20" SegTime="7" TimeStamp="2005-05-06T00:14:15" Prio="0"><Point x="12,22145" y="50,52817"/></Item><Item PointDist="158223" PointDescription="rechts abbiegen auf Dorfstrasse (K7880)" Turn="r" SegDescription="Dorfstrasse (K7880)" SegDist="120" SegTime="20" TimeStamp="2005-05-06T00:14:22" Prio="0"><Point x="12,22125" y="50,52821"/></Item><Item PointDist="158343" PointDescription="halb rechts halten auf Dorfstrasse (K7880)" Turn="hr" SegDescription="Dorfstrasse (K7880)" SegDist="100" SegTime="301" TimeStamp="2005-05-06T00:14:42" Prio="0"><Point x="12,22268" y="50,52867"/></Item><Item PointDist="158443" PointDescription="halb links halten" Turn="hl" SegDist="2229" SegTime="58" TimeStamp="2005-05-06T00:19:43" Prio="0"><Point x="12,22409" y="50,52878"/></Item><Item PointDist="160672" PointDescription="bei D 08543 Pöhl/Helmsgrün " Turn="sa" SegDescription="K7880\Helmsgrün-Dorfstrasse" SegDist="292" SegTime="34" TimeStamp="2005-05-06T00:20:41" ViaStation="true" Prio="0"><Point x="12,21873" y="50,54607"/></Item><Item PointDist="160964" PointDescription="in Helmsgrün halb rechts halten" Turn="hr" SegDist="2230" SegTime="179" TimeStamp="2005-05-06T00:21:15" Prio="0"><Point x="12,21923" y="50,54864"/></Item><Item PointDist="163194" PointDescription="in Herlasgrün rechts abbiegen auf Herlasgrün-Dorfstrasse (K7811)" Turn="r" SegDescription="Herlasgrün-Dorfstrasse (K7811)" SegDist="72" SegTime="19" TimeStamp="2005-05-06T00:24:14" Prio="0"><Point x="12,22564" y="50,56618"/></Item><Item PointDist="163266" PointDescription="bei D 08543 Herlasgrün " Turn="sa" SegDescription="K7811\Herlasgrün-Dorfstrasse" SegDist="92" SegTime="9" TimeStamp="2005-05-06T00:24:33" ViaStation="true" Prio="0"><Point x="12,22625" y="50,56674"/></Item><Item PointDist="163358" PointDescription="links abbiegen auf Herlasgrün-Christgrüner Strasse" Turn="l" SegDescription="Herlasgrün-Christgrüner Strasse" SegDist="310" SegTime="115" TimeStamp="2005-05-06T00:24:42" Prio="0"><Point x="12,227" y="50,56737"/></Item><Item PointDist="163668" PointDescription="geradeaus weiter auf Christgrüner Strasse" Turn="sa" SegDescription="Christgrüner Strasse" SegDist="750" SegTime="35" TimeStamp="2005-05-06T00:26:37" Prio="0"><Point x="12,22491" y="50,5696"/></Item><Item PointDist="164418" PointDescription="rechts abbiegen auf Dreckschänke (S297)" Turn="r" SegDescription="Dreckschänke (S297)" SegDist="770" SegTime="47" TimeStamp="2005-05-06T00:27:12" Prio="0"><Point x="12,22183" y="50,57566"/></Item><Item PointDist="165188" PointDescription="links abbiegen auf S298" Turn="l" SegDescription="S298" SegDist="1850" SegTime="108" TimeStamp="2005-05-06T00:27:59" Prio="0"><Point x="12,23183" y="50,5782"/></Item><Item PointDist="167038" PointDescription="in Reimersgrün links abbiegen" Turn="l" SegDist="1530" SegTime="188" TimeStamp="2005-05-06T00:29:47" Prio="0"><Point x="12,21602" y="50,59087"/></Item><Item PointDist="168568" PointDescription="halb rechts halten" Turn="hr" SegDist="1130" SegTime="77" TimeStamp="2005-05-06T00:32:55" Prio="0"><Point x="12,19888" y="50,59877"/></Item><Item PointDist="169698" PointDescription="in Coschütz rechts abbiegen auf Friedensstrasse (K7887)" Turn="r" SegDescription="Friedensstrasse (K7887)" SegDist="1100" SegTime="124" TimeStamp="2005-05-06T00:34:12" Prio="0"><Point x="12,18753" y="50,60568"/></Item><Item PointDist="170798" PointDescription="links abbiegen auf S298" Turn="l" SegDescription="S298" SegDist="1420" SegTime="88" TimeStamp="2005-05-06T00:36:16" Prio="0"><Point x="12,19414" y="50,6135"/></Item><Item PointDist="172218" PointDescription="rechts abbiegen auf Netzschkauer Strasse (S296)" Turn="r" SegDescription="Netzschkauer Strasse (S296)" SegDist="113" SegTime="33" TimeStamp="2005-05-06T00:37:44" Prio="0"><Point x="12,20127" y="50,6248"/></Item><Item PointDist="172331" PointDescription="bei D 07985 Elsterberg/Reuth " Turn="sa" SegDescription="S296\Netzschkauer Strasse" SegDist="3556" SegTime="266" TimeStamp="2005-05-06T00:38:17" ViaStation="true" Prio="0"><Point x="12,20287" y="50,62463"/></Item><Item PointDist="175887" PointDescription="bei D 08491 Netzschkau " Turn="sa" SegDescription="S296\Elsterberger Strasse" SegDist="97" SegTime="10" TimeStamp="2005-05-06T00:42:43" ViaStation="true" Prio="0"><Point x="12,24267" y="50,61036"/></Item><Item PointDist="175984" PointDescription="in Netzschkau links abbiegen auf Elsterberger Strasse (S296)" Turn="l" SegDescription="Elsterberger Strasse (S296)" SegDist="80" SegTime="12" TimeStamp="2005-05-06T00:42:53" Prio="0"><Point x="12,24401" y="50,61042"/></Item><Item PointDist="176064" PointDescription="rechts abbiegen auf Strasse der Einheit (S296)" Turn="r" SegDescription="Strasse der Einheit (S296)" SegDist="260" SegTime="23" TimeStamp="2005-05-06T00:43:05" Prio="0"><Point x="12,2447" y="50,61091"/></Item><Item PointDist="176324" PointDescription="halb rechts halten auf Strasse der Einheit (S296)" Turn="hr" SegDescription="Strasse der Einheit (S296)" SegDist="170" SegTime="17" TimeStamp="2005-05-06T00:43:28" Prio="0"><Point x="12,24692" y="50,61102"/></Item><Item PointDist="176494" PointDescription="links abbiegen auf B173 Plauener Strasse" Turn="l" SegDescription="B173 Plauener Strasse" SegDist="1518" SegTime="111" TimeStamp="2005-05-06T00:43:45" Prio="0"><Point x="12,24875" y="50,61198"/></Item><Item PointDist="178012" PointDescription="bei D 08499 Mylau/Obermylau " Turn="sa" SegDescription="B173\Netzschkauer Strasse" SegDist="508" SegTime="45" TimeStamp="2005-05-06T00:45:36" ViaStation="true" Prio="0"><Point x="12,2578" y="50,62193"/></Item><Item PointDist="178520" PointDescription="bei D 08499 Mylau/Obermylau " Turn="sa" SegDescription="B173\Robert-Georgi-Weg" SegDist="1863" SegTime="178" TimeStamp="2005-05-06T00:46:21" ViaStation="true" Prio="0"><Point x="12,26418" y="50,62096"/></Item><Item PointDist="180383" PointDescription="in Reichenbach im Vogtland links abbiegen auf B173/B94 Klinkhardtstrasse" Turn="l" SegDescription="B173/B94 Klinkhardtstrasse" SegDist="780" SegTime="73" TimeStamp="2005-05-06T00:49:19" Prio="0"><Point x="12,28664" y="50,61901"/></Item><Item PointDist="181163" PointDescription="links abbiegen auf B173/B94 Dr.-Külz-Strasse" Turn="l" SegDescription="B173/B94 Dr.-Külz-Strasse" SegDist="620" SegTime="47" TimeStamp="2005-05-06T00:50:32" Prio="0"><Point x="12,29198" y="50,62473"/></Item><Item PointDist="181783" PointDescription="rechts abbiegen auf B173 Friedensstrasse" Turn="r" SegDescription="B173 Friedensstrasse" SegDist="1220" SegTime="110" TimeStamp="2005-05-06T00:51:19" Prio="0"><Point x="12,2854" y="50,62846"/></Item><Item PointDist="183003" PointDescription="bei D 08468 Reichenbach " Turn="sa" SegDescription="B173\Friedensstrasse" SegDist="5153" SegTime="430" TimeStamp="2005-05-06T00:53:09" ViaStation="true" Prio="0"><Point x="12,30154" y="50,62797"/></Item><Item PointDist="188156" PointDescription="in Neumark geradeaus weiter auf B173" Turn="sa" SegDescription="B173" SegDist="750" SegTime="6" TimeStamp="2005-05-06T01:00:19" Prio="0"><Point x="12,35922" y="50,64623"/></Item><Item PointDist="188906" PointDescription="geradeaus weiter auf B173" Turn="sa" SegDescription="B173" SegDist="92" SegTime="56" TimeStamp="2005-05-06T01:00:25" Prio="0"><Point x="12,36441" y="50,65208"/></Item><Item PointDist="188998" PointDescription="bei D 08496 Neumark/Unterneumark " Turn="sa" SegDescription="B173" SegDist="4520" SegTime="265" TimeStamp="2005-05-06T01:01:21" ViaStation="true" Prio="0"><Point x="12,36486" y="50,65285"/></Item><Item PointDist="193518" PointDescription="in Schönfels links abbiegen auf Stenner Strasse" Turn="l" SegDescription="Stenner Strasse" SegDist="210" SegTime="44" TimeStamp="2005-05-06T01:05:46" Prio="0"><Point x="12,40865" y="50,67676"/></Item><Item PointDist="193728" PointDescription="geradeaus weiter auf Zwickauer Strasse (K9351)" Turn="sa" SegDescription="Zwickauer Strasse (K9351)" SegDist="54" SegTime="8" TimeStamp="2005-05-06T01:06:30" Prio="0"><Point x="12,40573" y="50,67636"/></Item><Item PointDist="193782" PointDescription="D 08115 Schönfels " Turn="sa" SegDescription="K9351\Zwickauer Strasse" SegDist="54" SegTime="27" TimeStamp="2005-05-06T01:06:38" ViaStation="true" Prio="0"><Point x="12,40509" y="50,67609"/></Item><Item PointDist="193836" PointDescription="halb rechts halten auf Stenner Strasse" Turn="hr" SegDescription="Stenner Strasse" SegDist="210" SegTime="38" TimeStamp="2005-05-06T01:07:05" Prio="0"><Point x="12,40573" y="50,67636"/></Item><Item PointDist="194046" PointDescription="links abbiegen auf B173 Neumarker Strasse" Turn="l" SegDescription="B173 Neumarker Strasse" SegDist="6766" SegTime="461" TimeStamp="2005-05-06T01:07:43" Prio="0"><Point x="12,40865" y="50,67676"/></Item><Item PointDist="200812" PointDescription="bei D 08056 Zwickau/Bahnhofsvorstadt " Turn="sa" SegDescription="B173\Reichenbacher Strasse" SegDist="904" SegTime="76" TimeStamp="2005-05-06T01:15:24" ViaStation="true" Prio="0"><Point x="12,47962" y="50,71357"/></Item><Item PointDist="201716" PointDescription="in Zwickau rechts abbiegen auf B173 Humboldtstrasse" Turn="r" SegDescription="B173 Humboldtstrasse" SegDist="520" SegTime="53" TimeStamp="2005-05-06T01:16:40" Prio="0"><Point x="12,48981" y="50,71823"/></Item><Item PointDist="202236" PointDescription="links abbiegen auf B173 Am Schwanenteich" Turn="l" SegDescription="B173 Am Schwanenteich" SegDist="140" SegTime="11" TimeStamp="2005-05-06T01:17:33" Prio="0"><Point x="12,49359" y="50,71426"/></Item><Item PointDist="202376" PointDescription="rechts halten auf B173 Dr.-Friedrichs-Ring" Turn="r" SegDescription="B173 Dr.-Friedrichs-Ring" SegDist="280" SegTime="20" TimeStamp="2005-05-06T01:17:44" Prio="0"><Point x="12,49542" y="50,71477"/></Item><Item PointDist="202656" PointDescription="geradeaus weiter auf B173 Glück-Auf-Brücke/Äussere Dresdner Strasse" Turn="sa" SegDescription="B173 Glück-Auf-Brücke/Äussere Dresdner Strasse" SegDist="8340" SegTime="527" TimeStamp="2005-05-06T01:18:04" Prio="0"><Point x="12,49945" y="50,71482"/></Item><Item PointDist="210996" PointDescription="rechts abbiegen auf Dresdner Strasse" Turn="r" SegDescription="Dresdner Strasse" SegDist="780" SegTime="113" TimeStamp="2005-05-06T01:26:51" Prio="0"><Point x="12,59666" y="50,74514"/></Item><Item PointDist="211776" PointDescription="geradeaus weiter auf Ã„ussere Zwickauer Strasse" Turn="sa" SegDescription="Äussere Zwickauer Strasse" SegDist="1670" SegTime="117" TimeStamp="2005-05-06T01:28:44" Prio="0"><Point x="12,6066" y="50,7471"/></Item><Item PointDist="213446" PointDescription="in Lichtenstein/Sa. geradeaus weiter auf Innere Zwickauer Strasse" Turn="sa" SegDescription="Innere Zwickauer Strasse" SegDist="327" SegTime="41" TimeStamp="2005-05-06T01:30:41" Prio="0"><Point x="12,62685" y="50,7547"/></Item><Item PointDist="213773" PointDescription="bei D 09350 Lichtenstein " Turn="sa" SegDescription="S255\Innere Zwickauer Strasse" SegDist="82" SegTime="30" TimeStamp="2005-05-06T01:31:22" ViaStation="true" Prio="0"><Point x="12,63073" y="50,75627"/></Item><Item PointDist="213855" PointDescription="rechts abbiegen auf Hartensteiner Strasse (S255)" Turn="r" SegDescription="Hartensteiner Strasse (S255)" SegDist="210" SegTime="7" TimeStamp="2005-05-06T01:31:52" Prio="0"><Point x="12,63175" y="50,75654"/></Item><Item PointDist="214065" PointDescription="rechts abbiegen auf Hartensteiner Strasse (S255)" Turn="r" SegDescription="Hartensteiner Strasse (S255)" SegDist="570" SegTime="65" TimeStamp="2005-05-06T01:31:59" Prio="0"><Point x="12,63325" y="50,75502"/></Item><Item PointDist="214635" PointDescription="rechts abbiegen auf Hartensteiner Strasse (S255)" Turn="r" SegDescription="Hartensteiner Strasse (S255)" SegDist="30" SegTime="52" TimeStamp="2005-05-06T01:33:04" Prio="0"><Point x="12,63592" y="50,75024"/></Item><Item PointDist="214665" PointDescription="halb links halten auf Hartensteiner Strasse (S255)" Turn="hl" SegDescription="Hartensteiner Strasse (S255)" SegDist="13000" SegTime="958" TimeStamp="2005-05-06T01:33:56" Prio="0"><Point x="12,6358" y="50,74998"/></Item><Item PointDist="227665" PointDescription="geradeaus weiter auf S283" Turn="sa" SegDescription="S283" SegDist="400" SegTime="92" TimeStamp="2005-05-06T01:49:54" Prio="0"><Point x="12,69692" y="50,65965"/></Item><Item PointDist="228065" PointDescription="rechts abbiegen auf S283" Turn="r" SegDescription="S283" SegDist="1900" SegTime="37" TimeStamp="2005-05-06T01:51:26" Prio="0"><Point x="12,69448" y="50,65644"/></Item><Item PointDist="229965" PointDescription="in Hartenstein links abbiegen auf August-Bebel-Strasse (S283)" Turn="l" SegDescription="August-Bebel-Strasse (S283)" SegDist="330" SegTime="37" TimeStamp="2005-05-06T01:52:03" Prio="0"><Point x="12,67448" y="50,66333"/></Item><Item PointDist="230295" PointDescription="geradeaus weiter auf Bahnhofstrasse (S284)" Turn="sa" SegDescription="Bahnhofstrasse (S284)" SegDist="6" SegTime="20" TimeStamp="2005-05-06T01:52:40" Prio="0"><Point x="12,67128" y="50,66155"/></Item><Item PointDist="230301" PointDescription="bei D 08118 Hartenstein " Turn="sa" SegDescription="S284\Bahnhofstrasse" SegDist="1189" SegTime="84" TimeStamp="2005-05-06T01:53:00" ViaStation="true" Prio="0"><Point x="12,67125" y="50,6615"/></Item><Item PointDist="231490" PointDescription="rechts abbiegen" Turn="r" SegDist="220" SegTime="24" TimeStamp="2005-05-06T01:54:24" Prio="0"><Point x="12,66372" y="50,65228"/></Item><Item PointDist="231710" PointDescription="links abbiegen" Turn="l" SegDist="130" SegTime="19" TimeStamp="2005-05-06T01:54:48" Prio="0"><Point x="12,66109" y="50,65194"/></Item><Item PointDist="231840" PointDescription="in Stein rechts abbiegen auf Langenbacher Strasse (K9309)" Turn="r" SegDescription="Langenbacher Strasse (K9309)" SegDist="130" SegTime="7" TimeStamp="2005-05-06T01:55:07" Prio="0"><Point x="12,66143" y="50,6509"/></Item><Item PointDist="231970" PointDescription="halb links halten auf Wildbacher Strasse (K9309)" Turn="hl" SegDescription="Wildbacher Strasse (K9309)" SegDist="1510" SegTime="186" TimeStamp="2005-05-06T01:55:14" Prio="0"><Point x="12,66" y="50,65024"/></Item><Item PointDist="233480" PointDescription="geradeaus weiter" Turn="sa" SegDist="180" SegTime="52" TimeStamp="2005-05-06T01:58:20" Prio="0"><Point x="12,65173" y="50,63936"/></Item><Item PointDist="233660" PointDescription="halb rechts halten auf Hartensteiner Strasse (K9109)" Turn="hr" SegDescription="Hartensteiner Strasse (K9109)" SegDist="1330" SegTime="105" TimeStamp="2005-05-06T01:59:12" Prio="0"><Point x="12,6534" y="50,6382"/></Item><Item PointDist="234990" PointDescription="in Wildbach rechts abbiegen auf Hartensteiner Strasse (K9109)" Turn="r" SegDescription="Hartensteiner Strasse (K9109)" SegDist="1840" SegTime="163" TimeStamp="2005-05-06T02:00:57" Prio="0"><Point x="12,64554" y="50,62853"/></Item><Item PointDist="236830" PointDescription="links abbiegen auf Silberbachstrasse" Turn="l" SegDescription="Silberbachstrasse" SegDist="490" SegTime="45" TimeStamp="2005-05-06T02:03:40" Prio="0"><Point x="12,64142" y="50,61336"/></Item><Item PointDist="237320" PointDescription="geradeaus weiter auf Zechenplatz " Turn="sa" SegDescription="Zechenplatz " SegDist="1670" SegTime="135" TimeStamp="2005-05-06T02:04:25" Prio="0"><Point x="12,6469" y="50,61072"/></Item><Item PointDist="238990" PointDescription="in Schlema geradeaus weiter auf Schneeberger Weg" Turn="sa" SegDescription="Schneeberger Weg" SegDist="30" SegTime="11" TimeStamp="2005-05-06T02:06:40" Prio="0"><Point x="12,65502" y="50,60139"/></Item><Item PointDist="239020" PointDescription="links abbiegen auf Zechenplatz" Turn="l" SegDescription="Zechenplatz" SegDist="60" SegTime="18" TimeStamp="2005-05-06T02:06:51" Prio="0"><Point x="12,65488" y="50,60114"/></Item><Item PointDist="239080" PointDescription="rechts abbiegen auf Friedensstrasse" Turn="r" SegDescription="Friedensstrasse" SegDist="410" SegTime="78" TimeStamp="2005-05-06T02:07:09" Prio="0"><Point x="12,65542" y="50,60074"/></Item><Item PointDist="239490" PointDescription="rechts abbiegen auf B169 Kobaltstrasse/Auer Strasse" Turn="r" SegDescription="B169 Kobaltstrasse/Auer Strasse" SegDist="1250" SegTime="105" TimeStamp="2005-05-06T02:08:27" Prio="0"><Point x="12,65089" y="50,59861"/></Item><Item PointDist="240740" PointDescription="in Schneeberg rechts abbiegen auf B169 Kobaltstrasse" Turn="r" SegDescription="B169 Kobaltstrasse" SegDist="8280" SegTime="664" TimeStamp="2005-05-06T02:10:12" Prio="0"><Point x="12,64319" y="50,58969"/></Item><Item PointDist="249020" PointDescription="in Hundshübel halb rechts halten auf B169 Hauptstrasse" Turn="hr" SegDescription="B169 Hauptstrasse" SegDist="4440" SegTime="286" TimeStamp="2005-05-06T02:21:16" Prio="0"><Point x="12,57633" y="50,54659"/></Item><Item PointDist="253460" PointDescription="in Stützengrün rechts abbiegen auf B169 Auerbacher Strasse" Turn="r" SegDescription="B169 Auerbacher Strasse" SegDist="10130" SegTime="766" TimeStamp="2005-05-06T02:26:02" Prio="0"><Point x="12,52721" y="50,53391"/></Item><Item PointDist="263590" PointDescription="in Rodewisch rechts abbiegen auf B169 Postplatz" Turn="r" SegDescription="B169 Postplatz" SegDist="170" SegTime="12" TimeStamp="2005-05-06T02:38:48" Prio="0"><Point x="12,40566" y="50,53118"/></Item><Item PointDist="263760" PointDescription="links abbiegen auf B169 Postplatz" Turn="l" SegDescription="B169 Postplatz" SegDist="544" SegTime="49" TimeStamp="2005-05-06T02:39:00" Prio="0"><Point x="12,40392" y="50,53211"/></Item><Item PointDist="264304" PointDescription="bei D 08228 Rodewisch " Turn="sa" SegDescription="B169\Lindenstrasse" SegDist="2415" SegTime="218" TimeStamp="2005-05-06T02:39:49" ViaStation="true" Prio="0"><Point x="12,40161" y="50,5289"/></Item><Item PointDist="266719" PointDescription="bei D 08209 Auerbach " Turn="sa" SegDescription="B169\Göltzschtalstrasse" SegDist="646" SegTime="58" TimeStamp="2005-05-06T02:43:27" ViaStation="true" Prio="0"><Point x="12,3979" y="50,50827"/></Item><Item PointDist="267365" PointDescription="in Auerbach/Vogtl. links abbiegen auf B169 Göltzschtalstrasse" Turn="l" SegDescription="B169 Göltzschtalstrasse" SegDist="1650" SegTime="160" TimeStamp="2005-05-06T02:44:25" Prio="0"><Point x="12,39793" y="50,50286"/></Item><Item PointDist="269015" PointDescription="in Ellefeld links abbiegen auf Neuberg" Turn="l" SegDescription="Neuberg" SegDist="250" SegTime="93" TimeStamp="2005-05-06T02:47:05" Prio="0"><Point x="12,39379" y="50,489"/></Item><Item PointDist="269265" PointDescription="rechts abbiegen auf Neuberg" Turn="r" SegDescription="Neuberg" SegDist="790" SegTime="127" TimeStamp="2005-05-06T02:48:38" Prio="0"><Point x="12,39629" y="50,4898"/></Item><Item PointDist="270055" PointDescription="rechts abbiegen auf Beerheider Strasse  (K7833)" Turn="r" SegDescription="Beerheider Strasse  (K7833)" SegDist="1410" SegTime="13" TimeStamp="2005-05-06T02:50:45" Prio="0"><Point x="12,40533" y="50,49366"/></Item><Item PointDist="271465" PointDescription="rechts abbiegen auf Beerheider Strasse (K7833)" Turn="r" SegDescription="Beerheider Strasse (K7833)" SegDist="923" SegTime="87" TimeStamp="2005-05-06T02:50:58" Prio="0"><Point x="12,42136" y="50,48718"/></Item><Item PointDist="272388" PointDescription="bei D 08209 Auerbach/Beerheide " Turn="sa" SegDescription="K7833\Rempesgrüner Strasse" SegDist="91" SegTime="30" TimeStamp="2005-05-06T02:52:25" ViaStation="true" Prio="0"><Point x="12,42487" y="50,4792"/></Item><Item PointDist="272479" PointDescription="in Beerheide links abbiegen auf Strasse des Friedens (K7826)" Turn="l" SegDescription="Strasse des Friedens (K7826)" SegDist="1040" SegTime="150" TimeStamp="2005-05-06T02:52:55" Prio="0"><Point x="12,42546" y="50,47847"/></Item><Item PointDist="273519" PointDescription="in Hohengrün rechts abbiegen auf Klingenthaler Strasse (S300)" Turn="r" SegDescription="Klingenthaler Strasse (S300)" SegDist="520" SegTime="16" TimeStamp="2005-05-06T02:55:25" Prio="0"><Point x="12,43305" y="50,48567"/></Item><Item PointDist="274039" PointDescription="links abbiegen" Turn="l" SegDist="200" SegTime="150" TimeStamp="2005-05-06T02:55:41" Prio="0"><Point x="12,43391" y="50,48116"/></Item><Item PointDist="274239" PointDescription="links abbiegen auf Schallerbachstrasse (K7822)" Turn="l" SegDescription="Schallerbachstrasse (K7822)" SegDist="2330" SegTime="45" TimeStamp="2005-05-06T02:58:11" Prio="0"><Point x="12,43586" y="50,47984"/></Item><Item PointDist="276569" PointDescription="in Brunn rechts abbiegen auf Schönheider Strasse (S278)" Turn="r" SegDescription="Schönheider Strasse (S278)" SegDist="7810" SegTime="723" TimeStamp="2005-05-06T02:58:56" Prio="0"><Point x="12,43583" y="50,50021"/></Item><Item PointDist="284379" PointDescription="in Schönheide halb rechts halten auf Hauptstrasse (S278)" Turn="hr" SegDescription="Hauptstrasse (S278)" SegDist="907" SegTime="86" TimeStamp="2005-05-06T03:10:59" Prio="0"><Point x="12,52204" y="50,50509"/></Item><Item PointDist="285286" PointDescription="D 08304 Schönheide " Turn="sa" SegDescription="S278\Hauptstrasse" SegDist="518" SegTime="72" TimeStamp="2005-05-06T03:12:25" ViaStation="true" Prio="0"><Point x="12,53336" y="50,50303"/></Item><Item PointDist="285804" PointDescription="halb links halten auf Hauptstrasse (S278)" Turn="hl" SegDescription="Hauptstrasse (S278)" SegDist="150" SegTime="18" TimeStamp="2005-05-06T03:13:37" Prio="0"><Point x="12,53994" y="50,50461"/></Item><Item PointDist="285954" PointDescription="geradeaus weiter auf Eibenstocker Strasse (S277)" Turn="sa" SegDescription="Eibenstocker Strasse (S277)" SegDist="1520" SegTime="187" TimeStamp="2005-05-06T03:13:55" Prio="0"><Point x="12,54119" y="50,50559"/></Item><Item PointDist="287474" PointDescription="rechts abbiegen auf B283 Muldenstrasse" Turn="r" SegDescription="B283 Muldenstrasse" SegDist="8880" SegTime="533" TimeStamp="2005-05-06T03:17:02" Prio="0"><Point x="12,55744" y="50,50457"/></Item><Item PointDist="296354" PointDescription="halb rechts halten auf Am Filz" Turn="hr" SegDescription="Am Filz" SegDist="860" SegTime="63" TimeStamp="2005-05-06T03:25:55" Prio="0"><Point x="12,49511" y="50,46782"/></Item><Item PointDist="297214" PointDescription="geradeaus weiter auf B283 Schönheider Strasse" Turn="sa" SegDescription="B283 Schönheider Strasse" SegDist="555" SegTime="60" TimeStamp="2005-05-06T03:26:58" Prio="0"><Point x="12,49073" y="50,46279"/></Item><Item PointDist="297769" PointDescription="bei D 08262 Tannenbergsthal/Jägersgrün " Turn="sa" SegDescription="B283\Schönheider Strasse" SegDist="3747" SegTime="225" TimeStamp="2005-05-06T03:27:58" ViaStation="true" Prio="0"><Point x="12,48844" y="50,45825"/></Item><Item PointDist="301516" PointDescription="bei D 08262 Tannenbergsthal " Turn="sa" SegDescription="B283\Klingenthaler Strasse" SegDist="7764" SegTime="548" TimeStamp="2005-05-06T03:31:43" ViaStation="true" Prio="0"><Point x="12,46112" y="50,43453"/></Item><Item PointDist="309280" PointDescription="in Klingenthal/Sa. links abbiegen auf B283 Auerbacher Strasse" Turn="l" SegDescription="B283 Auerbacher Strasse" SegDist="1410" SegTime="208" TimeStamp="2005-05-06T03:40:51" Prio="0"><Point x="12,4819" y="50,38576"/></Item><Item PointDist="310690" PointDescription="rechts abbiegen auf Mittelbergstrasse" Turn="r" SegDescription="Mittelbergstrasse" SegDist="580" SegTime="26" TimeStamp="2005-05-06T03:44:19" Prio="0"><Point x="12,47603" y="50,37537"/></Item><Item PointDist="311270" PointDescription="rechts abbiegen auf Falkensteiner Strasse (S304)" Turn="r" SegDescription="Falkensteiner Strasse (S304)" SegDist="1673" SegTime="181" TimeStamp="2005-05-06T03:44:45" Prio="0"><Point x="12,46946" y="50,37277"/></Item><Item PointDist="312943" PointDescription="bei D 08248 Klingenthal/Brunndöbra " Turn="sa" SegDescription="S304\Falkensteiner Strasse" SegDist="7942" SegTime="566" TimeStamp="2005-05-06T03:47:46" ViaStation="true" Prio="0"><Point x="12,45622" y="50,38453"/></Item><Item PointDist="320885" PointDescription="bei D 08223 Grünbach-Muldenberg " Turn="sa" SegDescription="S302/S304" SegDist="423" SegTime="2" TimeStamp="2005-05-06T03:57:12" ViaStation="true" Prio="0"><Point x="12,39973" y="50,41964"/></Item><Item PointDist="321308" PointDescription="halb links halten auf S304" Turn="hl" SegDescription="S304" SegDist="4137" SegTime="335" TimeStamp="2005-05-06T03:57:14" Prio="0"><Point x="12,39774" y="50,42322"/></Item><Item PointDist="325445" PointDescription="bei D 08223 Grünbach " Turn="sa" SegDescription="S304\Bahnhofstrasse" SegDist="399" SegTime="53" TimeStamp="2005-05-06T04:02:49" ViaStation="true" Prio="0"><Point x="12,36459" y="50,44618"/></Item><Item PointDist="325844" PointDescription="in Grünbach links abbiegen auf Neustädter Strasse (K7835)" Turn="l" SegDescription="Neustädter Strasse (K7835)" SegDist="60" SegTime="38" TimeStamp="2005-05-06T04:03:42" Prio="0"><Point x="12,36217" y="50,44933"/></Item><Item PointDist="325904" PointDescription="links abbiegen auf Siehdichfürer Strasse (K7835)" Turn="l" SegDescription="Siehdichfürer Strasse (K7835)" SegDist="2910" SegTime="245" TimeStamp="2005-05-06T04:04:20" Prio="0"><Point x="12,36146" y="50,44952"/></Item><Item PointDist="328814" PointDescription="in Neudorf links abbiegen auf Schönecker Strasse (S301)" Turn="l" SegDescription="Schönecker Strasse (S301)" SegDist="430" SegTime="50" TimeStamp="2005-05-06T04:08:25" Prio="0"><Point x="12,33196" y="50,44212"/></Item><Item PointDist="329244" PointDescription="links abbiegen auf Schönecker Strasse (S301)" Turn="l" SegDescription="Schönecker Strasse (S301)" SegDist="4465" SegTime="266" TimeStamp="2005-05-06T04:09:15" Prio="0"><Point x="12,33316" y="50,43841"/></Item><Item PointDist="333709" PointDescription="bei D 08261 Schöneck " Turn="sa" SegDescription="S301" SegDist="393" SegTime="17" TimeStamp="2005-05-06T04:13:41" ViaStation="true" Prio="0"><Point x="12,3372" y="50,40042"/></Item><Item PointDist="334102" PointDescription="in Schöneck/Vogtl. rechts abbiegen auf Falkensteiner Strasse (S301/S302)" Turn="r" SegDescription="Falkensteiner Strasse (S301/S302)" SegDist="20" SegTime="11" TimeStamp="2005-05-06T04:13:58" Prio="0"><Point x="12,33753" y="50,39691"/></Item><Item PointDist="334122" PointDescription="links abbiegen auf Albertplatz/Falkensteiner Strasse (S301/S302)" Turn="l" SegDescription="Albertplatz/Falkensteiner Strasse (S301/S302)" SegDist="630" SegTime="85" TimeStamp="2005-05-06T04:14:09" Prio="0"><Point x="12,33735" y="50,39681"/></Item><Item PointDist="334752" PointDescription="rechts abbiegen auf Klingenthaler Strasse (S301)" Turn="r" SegDescription="Klingenthaler Strasse (S301)" SegDist="600" SegTime="21" TimeStamp="2005-05-06T04:15:34" Prio="0"><Point x="12,34362" y="50,39344"/></Item><Item PointDist="335352" PointDescription="einfahren in Kreisverkehr " Turn="r" SegDist="40" SegTime="48" TimeStamp="2005-05-06T04:15:55" Prio="0"><Point x="12,3495" y="50,38969"/></Item><Item PointDist="335392" PointDescription="2. Möglichkeit aus Kreisverkehr ausfahren auf Kärnerstrasse (S305)" Turn="r" SegDescription="Kärnerstrasse (S305)" SegDist="6120" SegTime="475" TimeStamp="2005-05-06T04:16:43" Prio="0"><Point x="12,34966" y="50,38949"/></Item><Item PointDist="341512" PointDescription="rechts abbiegen auf B283" Turn="r" SegDescription="B283" SegDist="2316" SegTime="63" TimeStamp="2005-05-06T04:24:38" Prio="0"><Point x="12,37058" y="50,34307"/></Item><Item PointDist="343828" PointDescription="bei D 08258 Markneukirchen/Friebus " Turn="sa" SegDescription="B283" SegDist="4539" SegTime="342" TimeStamp="2005-05-06T04:25:41" ViaStation="true" Prio="0"><Point x="12,35151" y="50,32866"/></Item><Item PointDist="348367" PointDescription="rechts abbiegen auf B283" Turn="r" SegDescription="B283" SegDist="130" SegTime="24" TimeStamp="2005-05-06T04:31:23" Prio="0"><Point x="12,30708" y="50,30969"/></Item><Item PointDist="348497" PointDescription="in Siebenbrunn geradeaus weiter auf Am Bahnhof " Turn="sa" SegDescription="Am Bahnhof " SegDist="320" SegTime="65" TimeStamp="2005-05-06T04:31:47" Prio="0"><Point x="12,30595" y="50,30896"/></Item><Item PointDist="348817" PointDescription="links abbiegen auf Strässler Berg" Turn="l" SegDescription="Strässler Berg" SegDist="490" SegTime="121" TimeStamp="2005-05-06T04:32:52" Prio="0"><Point x="12,30217" y="50,30798"/></Item><Item PointDist="349307" PointDescription="geradeaus weiter auf Siebenbrunner Strasse" Turn="sa" SegDescription="Siebenbrunner Strasse" SegDist="680" SegTime="43" TimeStamp="2005-05-06T04:34:53" Prio="0"><Point x="12,29888" y="50,30423"/></Item><Item PointDist="349987" PointDescription="in Strässel links abbiegen auf Böhmische Strasse (K7846)" Turn="l" SegDescription="Böhmische Strasse (K7846)" SegDist="2460" SegTime="193" TimeStamp="2005-05-06T04:35:36" Prio="0"><Point x="12,29728" y="50,29896"/></Item><Item PointDist="352447" PointDescription="in Schönlind rechts abbiegen auf Markneukirchner Strasse (K7843)" Turn="r" SegDescription="Markneukirchner Strasse (K7843)" SegDist="30" SegTime="4" TimeStamp="2005-05-06T04:38:49" Prio="0"><Point x="12,31397" y="50,28425"/></Item><Item PointDist="352477" PointDescription="links abbiegen auf Landwüster Strasse (K7846)" Turn="l" SegDescription="Landwüster Strasse (K7846)" SegDist="2020" SegTime="182" TimeStamp="2005-05-06T04:38:53" Prio="0"><Point x="12,3142" y="50,28402"/></Item><Item PointDist="354497" PointDescription="in Landwüst halb rechts halten auf Schönlinder Strasse (K7844)" Turn="hr" SegDescription="Schönlinder Strasse (K7844)" SegDist="30" SegTime="4" TimeStamp="2005-05-06T04:41:55" Prio="0"><Point x="12,32864" y="50,27133"/></Item><Item PointDist="354527" PointDescription="rechts abbiegen auf Rauner Strasse (K7844)" Turn="r" SegDescription="Rauner Strasse (K7844)" SegDist="473" SegTime="199" TimeStamp="2005-05-06T04:41:59" Prio="0"><Point x="12,32848" y="50,27109"/></Item><Item PointDist="355000" PointDescription="bei D 08258 Landwüst " Turn="sa" SegDescription="K7844\Rauner Strasse" SegDist="1794" SegTime="28" TimeStamp="2005-05-06T04:45:18" ViaStation="true" Prio="0"><Point x="12,32194" y="50,27154"/></Item><Item PointDist="356794" PointDescription="geradeaus weiter auf B92/E49" Turn="sa" SegDescription="B92/E49" SegDist="5627" SegTime="395" TimeStamp="2005-05-06T04:45:46" Prio="0"><Point x="12,29975" y="50,26883"/></Item><Item PointDist="362421" PointDescription="bei D 08626 Adorf/Jugelsburg " Turn="sa" SegDescription="B92/E49" SegDist="2257" SegTime="181" TimeStamp="2005-05-06T04:52:21" ViaStation="true" Prio="0"><Point x="12,25288" y="50,30499"/></Item><Item PointDist="364678" PointDescription="bei D 08626 Adorf " Turn="sa" SegDescription="B92/E49\Oelsnitzer Strasse" SegDist="5913" SegTime="369" TimeStamp="2005-05-06T04:55:22" ViaStation="true" Prio="0"><Point x="12,25748" y="50,32437"/></Item><Item PointDist="370591" PointDescription="halb links halten" Turn="hl" SegDist="190" SegTime="43" TimeStamp="2005-05-06T05:01:31" Prio="0"><Point x="12,21624" y="50,36663"/></Item><Item PointDist="370781" PointDescription="geradeaus weiter auf B92/E49 Adorfer Strasse" Turn="sa" SegDescription="B92/E49 Adorfer Strasse" SegDist="620" SegTime="12" TimeStamp="2005-05-06T05:02:14" Prio="0"><Point x="12,21472" y="50,36786"/></Item><Item PointDist="371401" PointDescription="halb links halten" Turn="hl" SegDist="130" SegTime="18" TimeStamp="2005-05-06T05:02:26" Prio="0"><Point x="12,2089" y="50,37197"/></Item><Item PointDist="371531" PointDescription="rechts abbiegen" Turn="r" SegDist="200" SegTime="52" TimeStamp="2005-05-06T05:02:44" Prio="0"><Point x="12,20749" y="50,37262"/></Item><Item PointDist="371731" PointDescription="links abbiegen auf B92/E49 Adorfer Strasse" Turn="l" SegDescription="B92/E49 Adorfer Strasse" SegDist="5620" SegTime="338" TimeStamp="2005-05-06T05:03:36" Prio="0"><Point x="12,20676" y="50,37428"/></Item><Item PointDist="377351" PointDescription="in Oelsnitz links abbiegen auf Rosa-Luxemburg-Strasse (S311)" Turn="l" SegDescription="Rosa-Luxemburg-Strasse (S311)" SegDist="110" SegTime="19" TimeStamp="2005-05-06T05:09:14" Prio="0"><Point x="12,1735" y="50,41626"/></Item><Item PointDist="377461" PointDescription="links abbiegen auf Grabenstrasse (S311)" Turn="l" SegDescription="Grabenstrasse (S311)" SegDist="260" SegTime="34" TimeStamp="2005-05-06T05:09:33" Prio="0"><Point x="12,17221" y="50,41679"/></Item><Item PointDist="377721" PointDescription="links abbiegen auf Kirchplatz (S311)" Turn="l" SegDescription="Kirchplatz (S311)" SegDist="100" SegTime="5" TimeStamp="2005-05-06T05:10:07" Prio="0"><Point x="12,16933" y="50,41548"/></Item><Item PointDist="377821" PointDescription="rechts abbiegen auf Heppeplatz (S311)" Turn="r" SegDescription="Heppeplatz (S311)" SegDist="110" SegTime="12" TimeStamp="2005-05-06T05:10:12" Prio="0"><Point x="12,16847" y="50,41479"/></Item><Item PointDist="377931" PointDescription="links abbiegen auf Bahnhofstrasse (S307)" Turn="l" SegDescription="Bahnhofstrasse (S307)" SegDist="670" SegTime="152" TimeStamp="2005-05-06T05:10:24" Prio="0"><Point x="12,16733" y="50,41541"/></Item><Item PointDist="378601" PointDescription="rechts abbiegen auf Talsperrenstrasse (S310)" Turn="r" SegDescription="Talsperrenstrasse (S310)" SegDist="980" SegTime="244" TimeStamp="2005-05-06T05:12:56" Prio="0"><Point x="12,16149" y="50,41226"/></Item><Item PointDist="379581" PointDescription="rechts abbiegen auf Talsperrenstrasse (K7854)" Turn="r" SegDescription="Talsperrenstrasse (K7854)" SegDist="3660" SegTime="84" TimeStamp="2005-05-06T05:17:00" Prio="0"><Point x="12,14922" y="50,41313"/></Item><Item PointDist="383241" PointDescription="bei D 08606 Planschwitz " Turn="sa" SegDescription="K7854\Oelsnitzer Strasse" SegDist="50" SegTime="1" TimeStamp="2005-05-06T05:18:24" ViaStation="true" Prio="0"><Point x="12,10301" y="50,42002"/></Item><Item PointDist="383291" PointDescription="in Planschwitz links abbiegen auf Talsperrenstrasse (K7854)" Turn="l" SegDescription="Talsperrenstrasse (K7854)" SegDist="320" SegTime="85" TimeStamp="2005-05-06T05:18:25" Prio="0"><Point x="12,10234" y="50,42017"/></Item><Item PointDist="383611" PointDescription="links abbiegen" Turn="l" SegDist="2390" SegTime="194" TimeStamp="2005-05-06T05:19:50" Prio="0"><Point x="12,09876" y="50,41886"/></Item><Item PointDist="386001" PointDescription="in Bösenbrunn rechts abbiegen auf S310" Turn="r" SegDescription="S310" SegDist="540" SegTime="27" TimeStamp="2005-05-06T05:23:04" Prio="0"><Point x="12,09584" y="50,39946"/></Item><Item PointDist="386541" PointDescription="links abbiegen auf S310" Turn="l" SegDescription="S310" SegDist="2140" SegTime="150" TimeStamp="2005-05-06T05:23:31" Prio="0"><Point x="12,09108" y="50,40268"/></Item><Item PointDist="388681" PointDescription="in Dröda rechts abbiegen auf Hauptstrasse/Bobenneukirchener Strasse (S310)" Turn="r" SegDescription="Hauptstrasse/Bobenneukirchener Strasse (S310)" SegDist="70" SegTime="25" TimeStamp="2005-05-06T05:26:01" Prio="0"><Point x="12,06405" y="50,40219"/></Item><Item PointDist="388751" PointDescription="halb rechts halten auf Bobenneukirchener Strasse (S310)" Turn="hr" SegDescription="Bobenneukirchener Strasse (S310)" SegDist="206" SegTime="158" TimeStamp="2005-05-06T05:26:26" Prio="0"><Point x="12,06355" y="50,40269"/></Item><Item PointDist="388957" PointDescription="bei D 08538 Burgstein/Dröda " Turn="sa" SegDescription="S310\Bobenneukirchener Strasse" SegDist="2415" SegTime="40" TimeStamp="2005-05-06T05:29:04" ViaStation="true" Prio="0"><Point x="12,06391" y="50,40449"/></Item><Item PointDist="391372" PointDescription="in Pirk rechts abbiegen auf B173 Hofer Strasse" Turn="r" SegDescription="B173 Hofer Strasse" SegDist="440" SegTime="67" TimeStamp="2005-05-06T05:29:44" Prio="0"><Point x="12,06697" y="50,42462"/></Item><Item PointDist="391812" PointDescription="links abbiegen auf Zur Pirkmühle (K7859)" Turn="l" SegDescription="Zur Pirkmühle (K7859)" SegDist="843" SegTime="199" TimeStamp="2005-05-06T05:30:51" Prio="0"><Point x="12,07087" y="50,42752"/></Item><Item PointDist="392655" PointDescription="bei D 08538 Burgstein/Pirk " Turn="sa" SegDescription="K7859" SegDist="2818" SegTime="52" TimeStamp="2005-05-06T05:34:10" ViaStation="true" Prio="0"><Point x="12,06116" y="50,4292"/></Item><Item PointDist="395473" PointDescription="in Geilsdorf links abbiegen auf Winkel (K7859)" Turn="l" SegDescription="Winkel (K7859)" SegDist="2080" SegTime="212" TimeStamp="2005-05-06T05:35:02" Prio="0"><Point x="12,03292" y="50,42914"/></Item><Item PointDist="397553" PointDescription="in Schwand links abbiegen auf Weischlitzer Strasse (K7859)" Turn="l" SegDescription="Weischlitzer Strasse (K7859)" SegDist="220" SegTime="31" TimeStamp="2005-05-06T05:38:34" Prio="0"><Point x="12,00848" y="50,43411"/></Item><Item PointDist="397773" PointDescription="halb rechts halten auf Weischlitzer Strasse (K7859)" Turn="hr" SegDescription="Weischlitzer Strasse (K7859)" SegDist="2009" SegTime="192" TimeStamp="2005-05-06T05:39:05" Prio="0"><Point x="12,00766" y="50,43255"/></Item><Item PointDist="399782" PointDescription="bei D 08538 Burgstein/Kemnitz " Turn="sa" SegDescription="K7859" SegDist="477" SegTime="126" TimeStamp="2005-05-06T05:42:17" ViaStation="true" Prio="0"><Point x="11,98196" y="50,4299"/></Item><Item PointDist="400259" PointDescription="links abbiegen auf Kemnitzer Strasse " Turn="l" SegDescription="Kemnitzer Strasse " SegDist="1400" SegTime="20" TimeStamp="2005-05-06T05:44:23" Prio="0"><Point x="11,9765" y="50,4276"/></Item><Item PointDist="401659" PointDescription="in Krebes rechts abbiegen auf Burgsteinstrasse (K7860)" Turn="r" SegDescription="Burgsteinstrasse (K7860)" SegDist="580" SegTime="114" TimeStamp="2005-05-06T05:44:43" Prio="0"><Point x="11,98572" y="50,41839"/></Item><Item PointDist="402239" PointDescription="geradeaus weiter" Turn="sa" SegDist="880" SegTime="134" TimeStamp="2005-05-06T05:46:37" Prio="0"><Point x="11,97904" y="50,41547"/></Item><Item PointDist="403119" PointDescription="links abbiegen" Turn="l" SegDist="3170" SegTime="142" TimeStamp="2005-05-06T05:48:51" Prio="0"><Point x="11,96994" y="50,41028"/></Item><Item PointDist="406289" PointDescription="in Heinersgrün halb links halten auf An der Kapelle (K7855)" Turn="hl" SegDescription="An der Kapelle (K7855)" SegDist="1900" SegTime="300" TimeStamp="2005-05-06T05:51:13" Prio="0"><Point x="11,99692" y="50,38874"/></Item><Item PointDist="408189" PointDescription="rechts abbiegen" Turn="r" SegDist="410" SegTime="44" TimeStamp="2005-05-06T05:56:13" Prio="0"><Point x="12,01606" y="50,37803"/></Item><Item PointDist="408599" PointDescription="geradeaus weiter auf B173" Turn="sa" SegDescription="B173" SegDist="9213" SegTime="613" TimeStamp="2005-05-06T05:56:57" Prio="0"><Point x="12,01193" y="50,37553"/></Item><Item PointDist="417812" PointDescription="bei D95032 Hof " Turn="sa" SegDist="0" SegTime="0" TimeStamp="2005-05-06T06:07:10" Prio="0"><Point x="11,91306" y="50,32692"/></Item></WaypointList></TEF>\r
diff --git a/reference/track/TrkDB-GPil.pdb b/reference/track/TrkDB-GPil.pdb
new file mode 100644 (file)
index 0000000..00c0912
Binary files /dev/null and b/reference/track/TrkDB-GPil.pdb differ
diff --git a/reference/track/pathaway.mps b/reference/track/pathaway.mps
new file mode 100644 (file)
index 0000000..79061fa
Binary files /dev/null and b/reference/track/pathaway.mps differ
diff --git a/reference/track/pathaway.pdb b/reference/track/pathaway.pdb
new file mode 100644 (file)
index 0000000..5b86068
Binary files /dev/null and b/reference/track/pathaway.pdb differ
diff --git a/reference/track/tef_xml.sample.xml b/reference/track/tef_xml.sample.xml
new file mode 100644 (file)
index 0000000..ddb466e
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<TEF Comment="TourExchangeFormat" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Header Version="1.5" Datasource="RoutePlanningProgramm" Name="von bei D 95030 Hof/Innenstadt nach bei D95032 Hof " Software="MOTORRAD Tourenplaner 2005/2006 9.50" CreationTime="2005-05-05T20:40:31"><Setup CoordinateSystem="GeoDecimal" Axissystem="Math" Measure="metric"/><Route Distance="417812000" Duration="34238"/></Header><WaypointList ItemCount="262"><Item PointDist="0" PointDescription="bei D 95030 Hof/Innenstadt " Turn="sa" SegDescription="B2 Schleizer Strasse" SegDist="4320" SegTime="306" TimeStamp="2005-05-05T20:36:32" Prio="0"><Point x="11,91293" y="50,32684"/></Item><Item PointDist="4320" PointDescription="in Zedtwitz halb rechts halten auf B2 Hofer Strasse" Turn="hr" SegDescription="B2 Hofer Strasse" SegDist="2120" SegTime="147" TimeStamp="2005-05-05T20:41:38" Prio="0"><Point x="11,90373" y="50,36235"/></Item><Item PointDist="6440" PointDescription="rechts abbiegen auf B2" Turn="r" SegDescription="B2" SegDist="3078" SegTime="256" TimeStamp="2005-05-05T20:44:05" Prio="0"><Point x="11,8914" y="50,37236"/></Item><Item PointDist="9518" PointDescription="bei D 95183 Töpen " Turn="sa" SegDescription="B2\Hofer Strasse" SegDist="6492" SegTime="398" TimeStamp="2005-05-05T20:48:21" ViaStation="true" Prio="0"><Point x="11,86756" y="50,39372"/></Item><Item PointDist="16010" PointDescription="in Gefell links abbiegen auf B90 Friedensstrasse" Turn="l" SegDescription="B90 Friedensstrasse" SegDist="16810" SegTime="1064" TimeStamp="2005-05-05T20:54:59" Prio="0"><Point x="11,86064" y="50,44219"/></Item><Item PointDist="32820" PointDescription="in Lobenstein halb rechts halten auf B90 Hirschberger Strasse" Turn="hr" SegDescription="B90 Hirschberger Strasse" SegDist="690" SegTime="134" TimeStamp="2005-05-05T21:12:43" Prio="0"><Point x="11,65216" y="50,45091"/></Item><Item PointDist="33510" PointDescription="geradeaus weiter auf Strasse der Jugend (L1095)" Turn="sa" SegDescription="Strasse der Jugend (L1095)" SegDist="703" SegTime="16" TimeStamp="2005-05-05T21:14:57" Prio="0"><Point x="11,64293" y="50,45152"/></Item><Item PointDist="34213" PointDescription="bei D 07356 Lobenstein " Turn="sa" SegDescription="L1095\Strasse der Jugend" SegDist="724" SegTime="111" TimeStamp="2005-05-05T21:15:13" ViaStation="true" Prio="0"><Point x="11,64281" y="50,45756"/></Item><Item PointDist="34937" PointDescription="links abbiegen auf L1099" Turn="l" SegDescription="L1099" SegDist="1220" SegTime="67" TimeStamp="2005-05-05T21:17:04" Prio="0"><Point x="11,64815" y="50,46225"/></Item><Item PointDist="36157" PointDescription="rechts abbiegen" Turn="r" SegDist="900" SegTime="20" TimeStamp="2005-05-05T21:18:11" Prio="0"><Point x="11,64099" y="50,47227"/></Item><Item PointDist="37057" PointDescription="in Schönbrunn links abbiegen auf Schönbrunn" Turn="l" SegDescription="Schönbrunn" SegDist="60" SegTime="20" TimeStamp="2005-05-05T21:18:31" Prio="0"><Point x="11,65227" y="50,47546"/></Item><Item PointDist="37117" PointDescription="links abbiegen auf Schönbrunn" Turn="l" SegDescription="Schönbrunn" SegDist="110" SegTime="13" TimeStamp="2005-05-05T21:18:51" Prio="0"><Point x="11,65289" y="50,47575"/></Item><Item PointDist="37227" PointDescription="halb rechts halten auf Schönbrunn" Turn="hr" SegDescription="Schönbrunn" SegDist="70" SegTime="66" TimeStamp="2005-05-05T21:19:04" Prio="0"><Point x="11,65293" y="50,47667"/></Item><Item PointDist="37297" PointDescription="geradeaus weiter auf L1095 " Turn="sa" SegDescription="L1095 " SegDist="730" SegTime="5" TimeStamp="2005-05-05T21:20:10" Prio="0"><Point x="11,65362" y="50,47711"/></Item><Item PointDist="38027" PointDescription="halb links halten auf L1095 " Turn="hl" SegDescription="L1095 " SegDist="60" SegTime="5" TimeStamp="2005-05-05T21:20:15" Prio="0"><Point x="11,661" y="50,4808"/></Item><Item PointDist="38087" PointDescription="in Bellevue links abbiegen auf L1095" Turn="l" SegDescription="L1095" SegDist="7740" SegTime="610" TimeStamp="2005-05-05T21:20:20" Prio="0"><Point x="11,66163" y="50,48106"/></Item><Item PointDist="45827" PointDescription="in Saalburg geradeaus weiter auf L1095" Turn="sa" SegDescription="L1095" SegDist="80" SegTime="5" TimeStamp="2005-05-05T21:30:30" Prio="0"><Point x="11,72845" y="50,49956"/></Item><Item PointDist="45907" PointDescription="geradeaus weiter auf L1095" Turn="sa" SegDescription="L1095" SegDist="480" SegTime="64" TimeStamp="2005-05-05T21:30:35" Prio="0"><Point x="11,7291" y="50,50013"/></Item><Item PointDist="46387" PointDescription="links abbiegen auf L1095" Turn="l" SegDescription="L1095" SegDist="90" SegTime="17" TimeStamp="2005-05-05T21:31:39" Prio="0"><Point x="11,7341" y="50,50281"/></Item><Item PointDist="46477" PointDescription="rechts abbiegen auf Schleizer Strasse (L1095)" Turn="r" SegDescription="Schleizer Strasse (L1095)" SegDist="430" SegTime="81" TimeStamp="2005-05-05T21:31:56" Prio="0"><Point x="11,7334" y="50,50348"/></Item><Item PointDist="46907" PointDescription="bei D 07929 Saalburg-Ebersdorf/Saalburg " Turn="sa" SegDescription="L1095" SegDist="2011" SegTime="139" TimeStamp="2005-05-05T21:33:17" ViaStation="true" Prio="0"><Point x="11,73346" y="50,50719"/></Item><Item PointDist="48918" PointDescription="geradeaus weiter auf L1095" Turn="sa" SegDescription="L1095" SegDist="850" SegTime="88" TimeStamp="2005-05-05T21:35:36" Prio="0"><Point x="11,73867" y="50,52311"/></Item><Item PointDist="49768" PointDescription="links abbiegen" Turn="l" SegDist="2862" SegTime="224" TimeStamp="2005-05-05T21:37:04" Prio="0"><Point x="11,74796" y="50,52771"/></Item><Item PointDist="52630" PointDescription="bei D07907 Burgk/Burgkhammer " Turn="sa" SegDescription="K550" SegDist="2022" SegTime="122" TimeStamp="2005-05-05T21:40:48" ViaStation="true" Prio="0"><Point x="11,71402" y="50,52467"/></Item><Item PointDist="54652" PointDescription="rechts abbiegen auf L1101" Turn="r" SegDescription="L1101" SegDist="2200" SegTime="175" TimeStamp="2005-05-05T21:42:50" Prio="0"><Point x="11,70781" y="50,54068"/></Item><Item PointDist="56852" PointDescription="geradeaus weiter auf Burgkhammer " Turn="sa" SegDescription="Burgkhammer " SegDist="982" SegTime="16" TimeStamp="2005-05-05T21:45:45" Prio="0"><Point x="11,72492" y="50,54671"/></Item><Item PointDist="57834" PointDescription="bei D 07907 Burgk/Burgkhammer " Turn="sa" SegDescription="Burgkhammer" SegDist="22" SegTime="14" TimeStamp="2005-05-05T21:46:01" ViaStation="true" Prio="0"><Point x="11,71945" y="50,55144"/></Item><Item PointDist="57856" PointDescription="in Burgkhammer links abbiegen auf L1101 " Turn="l" SegDescription="L1101 " SegDist="3160" SegTime="219" TimeStamp="2005-05-05T21:46:15" Prio="0"><Point x="11,71946" y="50,55163"/></Item><Item PointDist="61016" PointDescription="links abbiegen" Turn="l" SegDist="4880" SegTime="348" TimeStamp="2005-05-05T21:49:54" Prio="0"><Point x="11,70781" y="50,54068"/></Item><Item PointDist="65896" PointDescription="links abbiegen auf L1095" Turn="l" SegDescription="L1095" SegDist="2520" SegTime="217" TimeStamp="2005-05-05T21:55:42" Prio="0"><Point x="11,74796" y="50,52771"/></Item><Item PointDist="68416" PointDescription="links abbiegen auf Burgker Chaussee (L1101)" Turn="l" SegDescription="Burgker Chaussee (L1101)" SegDist="3520" SegTime="258" TimeStamp="2005-05-05T21:59:19" Prio="0"><Point x="11,77272" y="50,54302"/></Item><Item PointDist="71936" PointDescription="links abbiegen auf Burgker Strasse (L1101)" Turn="l" SegDescription="Burgker Strasse (L1101)" SegDist="40" SegTime="108" TimeStamp="2005-05-05T22:03:37" Prio="0"><Point x="11,73423" y="50,55532"/></Item><Item PointDist="71976" PointDescription="halb rechts halten auf L2357" Turn="hr" SegDescription="L2357" SegDist="1195" SegTime="108" TimeStamp="2005-05-05T22:05:25" Prio="0"><Point x="11,73389" y="50,555"/></Item><Item PointDist="73171" PointDescription="bei D 07907 Burgk " Turn="sa" SegDescription="L2357" SegDist="1195" SegTime="4" TimeStamp="2005-05-05T22:07:13" ViaStation="true" Prio="0"><Point x="11,71981" y="50,55627"/></Item><Item PointDist="74366" PointDescription="geradeaus weiter auf Burgker Strasse (L1101)" Turn="sa" SegDescription="Burgker Strasse (L1101)" SegDist="40" SegTime="34" TimeStamp="2005-05-05T22:07:17" Prio="0"><Point x="11,73389" y="50,555"/></Item><Item PointDist="74406" PointDescription="geradeaus weiter auf L2357" Turn="sa" SegDescription="L2357" SegDist="424" SegTime="16" TimeStamp="2005-05-05T22:07:51" Prio="0"><Point x="11,73423" y="50,55532"/></Item><Item PointDist="74830" PointDescription="bei D 07907 Schleiz/Möschlitz " Turn="sa" SegDescription="L2357" SegDist="198" SegTime="99" TimeStamp="2005-05-05T22:08:07" ViaStation="true" Prio="0"><Point x="11,73688" y="50,55874"/></Item><Item PointDist="75028" PointDescription="links abbiegen" Turn="l" SegDist="1660" SegTime="55" TimeStamp="2005-05-05T22:09:46" Prio="0"><Point x="11,73818" y="50,56032"/></Item><Item PointDist="76688" PointDescription="in Grochwitz halb rechts halten auf Mühlenstrasse" Turn="hr" SegDescription="Mühlenstrasse" SegDist="110" SegTime="27" TimeStamp="2005-05-05T22:10:41" Prio="0"><Point x="11,72963" y="50,57023"/></Item><Item PointDist="76798" PointDescription="geradeaus weiter auf Sackgasse" Turn="sa" SegDescription="Sackgasse" SegDist="210" SegTime="158" TimeStamp="2005-05-05T22:11:08" Prio="0"><Point x="11,73022" y="50,57114"/></Item><Item PointDist="77008" PointDescription="geradeaus weiter " Turn="sa" SegDist="1670" SegTime="118" TimeStamp="2005-05-05T22:13:46" Prio="0"><Point x="11,7323" y="50,57225"/></Item><Item PointDist="78678" PointDescription="links abbiegen auf L1103 " Turn="l" SegDescription="L1103 " SegDist="1310" SegTime="2" TimeStamp="2005-05-05T22:15:44" Prio="0"><Point x="11,75048" y="50,57964"/></Item><Item PointDist="79988" PointDescription="links abbiegen auf L1103" Turn="l" SegDescription="L1103" SegDist="670" SegTime="68" TimeStamp="2005-05-05T22:15:46" Prio="0"><Point x="11,74212" y="50,58952"/></Item><Item PointDist="80658" PointDescription="in Crispendorf halb rechts halten auf Ortsstrasse (L1103)" Turn="hr" SegDescription="Ortsstrasse (L1103)" SegDist="410" SegTime="42" TimeStamp="2005-05-05T22:16:54" Prio="0"><Point x="11,73445" y="50,59219"/></Item><Item PointDist="81068" PointDescription="halb rechts halten auf Ortsstrasse (L1103)" Turn="hr" SegDescription="Ortsstrasse (L1103)" SegDist="1420" SegTime="187" TimeStamp="2005-05-05T22:17:36" Prio="0"><Point x="11,72976" y="50,59057"/></Item><Item PointDist="82488" PointDescription="halb rechts halten auf L1103" Turn="hr" SegDescription="L1103" SegDist="6140" SegTime="453" TimeStamp="2005-05-05T22:20:43" Prio="0"><Point x="11,71203" y="50,59226"/></Item><Item PointDist="88628" PointDescription="in Ziegenrück halb links halten auf Schleizer Strasse (L1103)" Turn="hl" SegDescription="Schleizer Strasse (L1103)" SegDist="430" SegTime="64" TimeStamp="2005-05-05T22:28:16" Prio="0"><Point x="11,651" y="50,60566"/></Item><Item PointDist="89058" PointDescription="rechts abbiegen auf Plothental (L2350)" Turn="r" SegDescription="Plothental (L2350)" SegDist="277" SegTime="59" TimeStamp="2005-05-05T22:29:20" Prio="0"><Point x="11,6498" y="50,60874"/></Item><Item PointDist="89335" PointDescription="bei D 07924 Ziegenrück " Turn="sa" SegDescription="L2350\Plothental" SegDist="4072" SegTime="367" TimeStamp="2005-05-05T22:30:19" ViaStation="true" Prio="0"><Point x="11,65335" y="50,60809"/></Item><Item PointDist="93407" PointDescription="in Tausa halb links halten auf Tausa (L2350)" Turn="hl" SegDescription="Tausa (L2350)" SegDist="1440" SegTime="217" TimeStamp="2005-05-05T22:36:26" Prio="0"><Point x="11,69355" y="50,62715"/></Item><Item PointDist="94847" PointDescription="in Bucha links abbiegen auf Ortsstrasse (L2350)" Turn="l" SegDescription="Ortsstrasse (L2350)" SegDist="1500" SegTime="220" TimeStamp="2005-05-05T22:40:03" Prio="0"><Point x="11,70687" y="50,63505"/></Item><Item PointDist="96347" PointDescription="rechts abbiegen auf L2350" Turn="r" SegDescription="L2350" SegDist="1790" SegTime="143" TimeStamp="2005-05-05T22:43:43" Prio="0"><Point x="11,70356" y="50,64738"/></Item><Item PointDist="98137" PointDescription="in Knau halb links halten auf Hauptstrasse (L2349)" Turn="hl" SegDescription="Hauptstrasse (L2349)" SegDist="284" SegTime="54" TimeStamp="2005-05-05T22:46:06" Prio="0"><Point x="11,71955" y="50,65222"/></Item><Item PointDist="98421" PointDescription="bei D 07389 Knau " Turn="sa" SegDescription="L2349\Hauptstrasse" SegDist="269" SegTime="445" TimeStamp="2005-05-05T22:47:00" ViaStation="true" Prio="0"><Point x="11,72288" y="50,65084"/></Item><Item PointDist="98690" PointDescription="links abbiegen auf Hauptstrasse (L2349)" Turn="l" SegDescription="Hauptstrasse (L2349)" SegDist="4426" SegTime="145" TimeStamp="2005-05-05T22:54:25" Prio="0"><Point x="11,7256" y="50,64925"/></Item><Item PointDist="103116" PointDescription="bei D 07907 Plothen " Turn="sa" SegDescription="L2349\Ortsstrasse" SegDist="3689" SegTime="332" TimeStamp="2005-05-05T22:56:50" ViaStation="true" Prio="0"><Point x="11,77321" y="50,63884"/></Item><Item PointDist="106805" PointDescription="in Dittersdorf rechts abbiegen auf L1077" Turn="r" SegDescription="L1077" SegDist="3880" SegTime="274" TimeStamp="2005-05-05T23:02:22" Prio="0"><Point x="11,81631" y="50,6435"/></Item><Item PointDist="110685" PointDescription="rechts abbiegen auf Ziegelei" Turn="r" SegDescription="Ziegelei" SegDist="100" SegTime="41" TimeStamp="2005-05-05T23:06:56" Prio="0"><Point x="11,82502" y="50,61031"/></Item><Item PointDist="110785" PointDescription="halb rechts halten auf B2" Turn="hr" SegDescription="B2" SegDist="690" SegTime="8" TimeStamp="2005-05-05T23:07:37" Prio="0"><Point x="11,82507" y="50,60955"/></Item><Item PointDist="111475" PointDescription="in Oettersdorf links abbiegen auf Löhmaer Weg  (K301)" Turn="l" SegDescription="Löhmaer Weg  (K301)" SegDist="180" SegTime="31" TimeStamp="2005-05-05T23:07:45" Prio="0"><Point x="11,82391" y="50,60362"/></Item><Item PointDist="111655" PointDescription="rechts abbiegen auf Löhmaer Weg  (K301)" Turn="r" SegDescription="Löhmaer Weg  (K301)" SegDist="260" SegTime="7" TimeStamp="2005-05-05T23:08:16" Prio="0"><Point x="11,82582" y="50,60472"/></Item><Item PointDist="111915" PointDescription="links abbiegen auf Löhmaer Weg (K301)" Turn="l" SegDescription="Löhmaer Weg (K301)" SegDist="2050" SegTime="172" TimeStamp="2005-05-05T23:08:23" Prio="0"><Point x="11,8281" y="50,60284"/></Item><Item PointDist="113965" PointDescription="rechts abbiegen" Turn="r" SegDist="330" SegTime="19" TimeStamp="2005-05-05T23:11:15" Prio="0"><Point x="11,84991" y="50,6143"/></Item><Item PointDist="114295" PointDescription="in Löhma links abbiegen auf Ortsstrasse" Turn="l" SegDescription="Ortsstrasse" SegDist="210" SegTime="63" TimeStamp="2005-05-05T23:11:34" Prio="0"><Point x="11,85166" y="50,61166"/></Item><Item PointDist="114505" PointDescription="geradeaus weiter " Turn="sa" SegDist="2300" SegTime="188" TimeStamp="2005-05-05T23:12:37" Prio="0"><Point x="11,85462" y="50,61161"/></Item><Item PointDist="116805" PointDescription="in Kirschkau geradeaus weiter auf Ortsstrasse" Turn="sa" SegDescription="Ortsstrasse" SegDist="260" SegTime="49" TimeStamp="2005-05-05T23:15:45" Prio="0"><Point x="11,88309" y="50,60609"/></Item><Item PointDist="117065" PointDescription="rechts abbiegen auf Ortsstrasse" Turn="r" SegDescription="Ortsstrasse" SegDist="70" SegTime="20" TimeStamp="2005-05-05T23:16:34" Prio="0"><Point x="11,88594" y="50,60469"/></Item><Item PointDist="117135" PointDescription="rechts abbiegen auf Ortsstrasse" Turn="r" SegDescription="Ortsstrasse" SegDist="110" SegTime="13" TimeStamp="2005-05-05T23:16:54" Prio="0"><Point x="11,88574" y="50,60413"/></Item><Item PointDist="117245" PointDescription="links abbiegen auf Ortsstrasse" Turn="l" SegDescription="Ortsstrasse" SegDist="70" SegTime="9" TimeStamp="2005-05-05T23:17:07" Prio="0"><Point x="11,88462" y="50,60354"/></Item><Item PointDist="117315" PointDescription="rechts abbiegen auf Ortsstrasse" Turn="r" SegDescription="Ortsstrasse" SegDist="50" SegTime="56" TimeStamp="2005-05-05T23:17:16" Prio="0"><Point x="11,88556" y="50,60331"/></Item><Item PointDist="117365" PointDescription="geradeaus weiter auf B94 " Turn="sa" SegDescription="B94 " SegDist="1040" SegTime="95" TimeStamp="2005-05-05T23:18:12" Prio="0"><Point x="11,88541" y="50,60292"/></Item><Item PointDist="118405" PointDescription="rechts abbiegen auf B94" Turn="r" SegDescription="B94" SegDist="480" SegTime="49" TimeStamp="2005-05-05T23:19:47" Prio="0"><Point x="11,88776" y="50,59435"/></Item><Item PointDist="118885" PointDescription="links abbiegen auf Dorfstrasse" Turn="l" SegDescription="Dorfstrasse" SegDist="340" SegTime="19" TimeStamp="2005-05-05T23:20:36" Prio="0"><Point x="11,88475" y="50,59056"/></Item><Item PointDist="119225" PointDescription="in Lössau links abbiegen" Turn="l" SegDist="3000" SegTime="241" TimeStamp="2005-05-05T23:20:55" Prio="0"><Point x="11,88621" y="50,5878"/></Item><Item PointDist="122225" PointDescription="bei D 07907 Schleiz/Langenbuch " Turn="sa" SegDescription="K304\Lössauer Strasse" SegDist="153" SegTime="12" TimeStamp="2005-05-05T23:24:56" ViaStation="true" Prio="0"><Point x="11,90733" y="50,56821"/></Item><Item PointDist="122378" PointDescription="in Langenbuch links abbiegen auf Thierbacher Strasse (L2348)" Turn="l" SegDescription="Thierbacher Strasse (L2348)" SegDist="1940" SegTime="211" TimeStamp="2005-05-05T23:25:08" Prio="0"><Point x="11,90787" y="50,56691"/></Item><Item PointDist="124318" PointDescription="geradeaus weiter" Turn="sa" SegDist="4940" SegTime="456" TimeStamp="2005-05-05T23:28:39" Prio="0"><Point x="11,93059" y="50,57547"/></Item><Item PointDist="129258" PointDescription="in Pausa/Vogtl. rechts abbiegen" Turn="r" SegDist="230" SegTime="28" TimeStamp="2005-05-05T23:36:15" Prio="0"><Point x="11,99148" y="50,58023"/></Item><Item PointDist="129488" PointDescription="rechts abbiegen auf Plauensche Strasse (S316)" Turn="r" SegDescription="Plauensche Strasse (S316)" SegDist="270" SegTime="21" TimeStamp="2005-05-05T23:36:43" Prio="0"><Point x="11,99249" y="50,5783"/></Item><Item PointDist="129758" PointDescription="in Oberreichenau halb links halten auf Am Mühlgraben (S316)" Turn="hl" SegDescription="Am Mühlgraben (S316)" SegDist="133" SegTime="9" TimeStamp="2005-05-05T23:37:04" Prio="0"><Point x="11,99057" y="50,57624"/></Item><Item PointDist="129891" PointDescription="bei D 07952 Pausa/Oberreichenau " Turn="sa" SegDescription="S316\Am Mühlgraben" SegDist="8503" SegTime="685" TimeStamp="2005-05-05T23:37:13" ViaStation="true" Prio="0"><Point x="11,99127" y="50,57521"/></Item><Item PointDist="138394" PointDescription="in Syrau halb rechts halten auf B282/E49 Hauptstrasse" Turn="hr" SegDescription="B282/E49 Hauptstrasse" SegDist="107" SegTime="15" TimeStamp="2005-05-05T23:48:38" Prio="0"><Point x="12,08104" y="50,54202"/></Item><Item PointDist="138501" PointDescription="bei D 08548 Syrau " Turn="sa" SegDescription="B282/E49\Hauptstrasse" SegDist="2884" SegTime="195" TimeStamp="2005-05-05T23:48:53" ViaStation="true" Prio="0"><Point x="12,08196" y="50,54133"/></Item><Item PointDist="141385" PointDescription="rechts abbiegen auf Pausaer Strasse" Turn="r" SegDescription="Pausaer Strasse" SegDist="1300" SegTime="107" TimeStamp="2005-05-05T23:52:08" Prio="0"><Point x="12,11052" y="50,5255"/></Item><Item PointDist="142685" PointDescription="rechts abbiegen auf B92/E49 Pausaer Strasse" Turn="r" SegDescription="B92/E49 Pausaer Strasse" SegDist="1340" SegTime="105" TimeStamp="2005-05-05T23:53:55" Prio="0"><Point x="12,12004" y="50,51718"/></Item><Item PointDist="144025" PointDescription="in Plauen links abbiegen auf Martin-Luther-Strasse" Turn="l" SegDescription="Martin-Luther-Strasse" SegDist="989" SegTime="71" TimeStamp="2005-05-05T23:55:40" Prio="0"><Point x="12,12962" y="50,50751"/></Item><Item PointDist="145014" PointDescription="bei D 08525 Plauen/Preißelpöhl " Turn="sa" SegDescription="Martin-Luther-Strasse" SegDist="339" SegTime="42" TimeStamp="2005-05-05T23:56:51" ViaStation="true" Prio="0"><Point x="12,14214" y="50,50466"/></Item><Item PointDist="145353" PointDescription="links abbiegen auf Lessingstrasse" Turn="l" SegDescription="Lessingstrasse" SegDist="510" SegTime="86" TimeStamp="2005-05-05T23:57:33" Prio="0"><Point x="12,14503" y="50,50233"/></Item><Item PointDist="145863" PointDescription="links abbiegen auf B173 Hammerstrasse" Turn="l" SegDescription="B173 Hammerstrasse" SegDist="3850" SegTime="318" TimeStamp="2005-05-05T23:58:59" Prio="0"><Point x="12,15144" y="50,50178"/></Item><Item PointDist="149713" PointDescription="links abbiegen auf Voigtsgrüner Weg (K6605)" Turn="l" SegDescription="Voigtsgrüner Weg (K6605)" SegDist="1370" SegTime="23" TimeStamp="2005-05-06T00:04:17" Prio="0"><Point x="12,18231" y="50,4977"/></Item><Item PointDist="151083" PointDescription="rechts abbiegen auf Zum Plom" Turn="r" SegDescription="Zum Plom" SegDist="1480" SegTime="146" TimeStamp="2005-05-06T00:04:40" Prio="0"><Point x="12,19489" y="50,50642"/></Item><Item PointDist="152563" PointDescription="rechts abbiegen" Turn="r" SegDist="650" SegTime="22" TimeStamp="2005-05-06T00:07:06" Prio="0"><Point x="12,21222" y="50,50799"/></Item><Item PointDist="153213" PointDescription="in Neuensalz links abbiegen auf B169" Turn="l" SegDescription="B169" SegDist="70" SegTime="10" TimeStamp="2005-05-06T00:07:28" Prio="0"><Point x="12,21867" y="50,50401"/></Item><Item PointDist="153283" PointDescription="links abbiegen auf B169 Alte Plauener Strasse" Turn="l" SegDescription="B169 Alte Plauener Strasse" SegDist="110" SegTime="4" TimeStamp="2005-05-06T00:07:38" Prio="0"><Point x="12,21954" y="50,50388"/></Item><Item PointDist="153393" PointDescription="geradeaus weiter auf B173 Hauptstrasse" Turn="sa" SegDescription="B173 Hauptstrasse" SegDist="511" SegTime="46" TimeStamp="2005-05-06T00:07:42" Prio="0"><Point x="12,22049" y="50,50457"/></Item><Item PointDist="153904" PointDescription="bei D 08541 Neuensalz " Turn="sa" SegDescription="B173\Hauptstrasse" SegDist="1889" SegTime="139" TimeStamp="2005-05-06T00:08:28" ViaStation="true" Prio="0"><Point x="12,22704" y="50,50632"/></Item><Item PointDist="155793" PointDescription="in Thossfell geradeaus weiter auf B173 Hauptstrasse" Turn="sa" SegDescription="B173 Hauptstrasse" SegDist="150" SegTime="22" TimeStamp="2005-05-06T00:10:47" Prio="0"><Point x="12,24283" y="50,51914"/></Item><Item PointDist="155943" PointDescription="geradeaus weiter auf B173 Hauptstrasse" Turn="sa" SegDescription="B173 Hauptstrasse" SegDist="460" SegTime="21" TimeStamp="2005-05-06T00:11:09" Prio="0"><Point x="12,24339" y="50,52043"/></Item><Item PointDist="156403" PointDescription="links abbiegen auf Gansgrüner Strasse (K7880)" Turn="l" SegDescription="Gansgrüner Strasse (K7880)" SegDist="20" SegTime="39" TimeStamp="2005-05-06T00:11:30" Prio="0"><Point x="12,24441" y="50,52453"/></Item><Item PointDist="156423" PointDescription="links abbiegen auf Gansgrüner Strasse (K7880)" Turn="l" SegDescription="Gansgrüner Strasse (K7880)" SegDist="1780" SegTime="126" TimeStamp="2005-05-06T00:12:09" Prio="0"><Point x="12,24423" y="50,52464"/></Item><Item PointDist="158203" PointDescription="in Gansgrün links abbiegen auf Dorfstrasse" Turn="l" SegDescription="Dorfstrasse" SegDist="20" SegTime="7" TimeStamp="2005-05-06T00:14:15" Prio="0"><Point x="12,22145" y="50,52817"/></Item><Item PointDist="158223" PointDescription="rechts abbiegen auf Dorfstrasse (K7880)" Turn="r" SegDescription="Dorfstrasse (K7880)" SegDist="120" SegTime="20" TimeStamp="2005-05-06T00:14:22" Prio="0"><Point x="12,22125" y="50,52821"/></Item><Item PointDist="158343" PointDescription="halb rechts halten auf Dorfstrasse (K7880)" Turn="hr" SegDescription="Dorfstrasse (K7880)" SegDist="100" SegTime="301" TimeStamp="2005-05-06T00:14:42" Prio="0"><Point x="12,22268" y="50,52867"/></Item><Item PointDist="158443" PointDescription="halb links halten" Turn="hl" SegDist="2229" SegTime="58" TimeStamp="2005-05-06T00:19:43" Prio="0"><Point x="12,22409" y="50,52878"/></Item><Item PointDist="160672" PointDescription="bei D 08543 Pöhl/Helmsgrün " Turn="sa" SegDescription="K7880\Helmsgrün-Dorfstrasse" SegDist="292" SegTime="34" TimeStamp="2005-05-06T00:20:41" ViaStation="true" Prio="0"><Point x="12,21873" y="50,54607"/></Item><Item PointDist="160964" PointDescription="in Helmsgrün halb rechts halten" Turn="hr" SegDist="2230" SegTime="179" TimeStamp="2005-05-06T00:21:15" Prio="0"><Point x="12,21923" y="50,54864"/></Item><Item PointDist="163194" PointDescription="in Herlasgrün rechts abbiegen auf Herlasgrün-Dorfstrasse (K7811)" Turn="r" SegDescription="Herlasgrün-Dorfstrasse (K7811)" SegDist="72" SegTime="19" TimeStamp="2005-05-06T00:24:14" Prio="0"><Point x="12,22564" y="50,56618"/></Item><Item PointDist="163266" PointDescription="bei D 08543 Herlasgrün " Turn="sa" SegDescription="K7811\Herlasgrün-Dorfstrasse" SegDist="92" SegTime="9" TimeStamp="2005-05-06T00:24:33" ViaStation="true" Prio="0"><Point x="12,22625" y="50,56674"/></Item><Item PointDist="163358" PointDescription="links abbiegen auf Herlasgrün-Christgrüner Strasse" Turn="l" SegDescription="Herlasgrün-Christgrüner Strasse" SegDist="310" SegTime="115" TimeStamp="2005-05-06T00:24:42" Prio="0"><Point x="12,227" y="50,56737"/></Item><Item PointDist="163668" PointDescription="geradeaus weiter auf Christgrüner Strasse" Turn="sa" SegDescription="Christgrüner Strasse" SegDist="750" SegTime="35" TimeStamp="2005-05-06T00:26:37" Prio="0"><Point x="12,22491" y="50,5696"/></Item><Item PointDist="164418" PointDescription="rechts abbiegen auf Dreckschänke (S297)" Turn="r" SegDescription="Dreckschänke (S297)" SegDist="770" SegTime="47" TimeStamp="2005-05-06T00:27:12" Prio="0"><Point x="12,22183" y="50,57566"/></Item><Item PointDist="165188" PointDescription="links abbiegen auf S298" Turn="l" SegDescription="S298" SegDist="1850" SegTime="108" TimeStamp="2005-05-06T00:27:59" Prio="0"><Point x="12,23183" y="50,5782"/></Item><Item PointDist="167038" PointDescription="in Reimersgrün links abbiegen" Turn="l" SegDist="1530" SegTime="188" TimeStamp="2005-05-06T00:29:47" Prio="0"><Point x="12,21602" y="50,59087"/></Item><Item PointDist="168568" PointDescription="halb rechts halten" Turn="hr" SegDist="1130" SegTime="77" TimeStamp="2005-05-06T00:32:55" Prio="0"><Point x="12,19888" y="50,59877"/></Item><Item PointDist="169698" PointDescription="in Coschütz rechts abbiegen auf Friedensstrasse (K7887)" Turn="r" SegDescription="Friedensstrasse (K7887)" SegDist="1100" SegTime="124" TimeStamp="2005-05-06T00:34:12" Prio="0"><Point x="12,18753" y="50,60568"/></Item><Item PointDist="170798" PointDescription="links abbiegen auf S298" Turn="l" SegDescription="S298" SegDist="1420" SegTime="88" TimeStamp="2005-05-06T00:36:16" Prio="0"><Point x="12,19414" y="50,6135"/></Item><Item PointDist="172218" PointDescription="rechts abbiegen auf Netzschkauer Strasse (S296)" Turn="r" SegDescription="Netzschkauer Strasse (S296)" SegDist="113" SegTime="33" TimeStamp="2005-05-06T00:37:44" Prio="0"><Point x="12,20127" y="50,6248"/></Item><Item PointDist="172331" PointDescription="bei D 07985 Elsterberg/Reuth " Turn="sa" SegDescription="S296\Netzschkauer Strasse" SegDist="3556" SegTime="266" TimeStamp="2005-05-06T00:38:17" ViaStation="true" Prio="0"><Point x="12,20287" y="50,62463"/></Item><Item PointDist="175887" PointDescription="bei D 08491 Netzschkau " Turn="sa" SegDescription="S296\Elsterberger Strasse" SegDist="97" SegTime="10" TimeStamp="2005-05-06T00:42:43" ViaStation="true" Prio="0"><Point x="12,24267" y="50,61036"/></Item><Item PointDist="175984" PointDescription="in Netzschkau links abbiegen auf Elsterberger Strasse (S296)" Turn="l" SegDescription="Elsterberger Strasse (S296)" SegDist="80" SegTime="12" TimeStamp="2005-05-06T00:42:53" Prio="0"><Point x="12,24401" y="50,61042"/></Item><Item PointDist="176064" PointDescription="rechts abbiegen auf Strasse der Einheit (S296)" Turn="r" SegDescription="Strasse der Einheit (S296)" SegDist="260" SegTime="23" TimeStamp="2005-05-06T00:43:05" Prio="0"><Point x="12,2447" y="50,61091"/></Item><Item PointDist="176324" PointDescription="halb rechts halten auf Strasse der Einheit (S296)" Turn="hr" SegDescription="Strasse der Einheit (S296)" SegDist="170" SegTime="17" TimeStamp="2005-05-06T00:43:28" Prio="0"><Point x="12,24692" y="50,61102"/></Item><Item PointDist="176494" PointDescription="links abbiegen auf B173 Plauener Strasse" Turn="l" SegDescription="B173 Plauener Strasse" SegDist="1518" SegTime="111" TimeStamp="2005-05-06T00:43:45" Prio="0"><Point x="12,24875" y="50,61198"/></Item><Item PointDist="178012" PointDescription="bei D 08499 Mylau/Obermylau " Turn="sa" SegDescription="B173\Netzschkauer Strasse" SegDist="508" SegTime="45" TimeStamp="2005-05-06T00:45:36" ViaStation="true" Prio="0"><Point x="12,2578" y="50,62193"/></Item><Item PointDist="178520" PointDescription="bei D 08499 Mylau/Obermylau " Turn="sa" SegDescription="B173\Robert-Georgi-Weg" SegDist="1863" SegTime="178" TimeStamp="2005-05-06T00:46:21" ViaStation="true" Prio="0"><Point x="12,26418" y="50,62096"/></Item><Item PointDist="180383" PointDescription="in Reichenbach im Vogtland links abbiegen auf B173/B94 Klinkhardtstrasse" Turn="l" SegDescription="B173/B94 Klinkhardtstrasse" SegDist="780" SegTime="73" TimeStamp="2005-05-06T00:49:19" Prio="0"><Point x="12,28664" y="50,61901"/></Item><Item PointDist="181163" PointDescription="links abbiegen auf B173/B94 Dr.-Külz-Strasse" Turn="l" SegDescription="B173/B94 Dr.-Külz-Strasse" SegDist="620" SegTime="47" TimeStamp="2005-05-06T00:50:32" Prio="0"><Point x="12,29198" y="50,62473"/></Item><Item PointDist="181783" PointDescription="rechts abbiegen auf B173 Friedensstrasse" Turn="r" SegDescription="B173 Friedensstrasse" SegDist="1220" SegTime="110" TimeStamp="2005-05-06T00:51:19" Prio="0"><Point x="12,2854" y="50,62846"/></Item><Item PointDist="183003" PointDescription="bei D 08468 Reichenbach " Turn="sa" SegDescription="B173\Friedensstrasse" SegDist="5153" SegTime="430" TimeStamp="2005-05-06T00:53:09" ViaStation="true" Prio="0"><Point x="12,30154" y="50,62797"/></Item><Item PointDist="188156" PointDescription="in Neumark geradeaus weiter auf B173" Turn="sa" SegDescription="B173" SegDist="750" SegTime="6" TimeStamp="2005-05-06T01:00:19" Prio="0"><Point x="12,35922" y="50,64623"/></Item><Item PointDist="188906" PointDescription="geradeaus weiter auf B173" Turn="sa" SegDescription="B173" SegDist="92" SegTime="56" TimeStamp="2005-05-06T01:00:25" Prio="0"><Point x="12,36441" y="50,65208"/></Item><Item PointDist="188998" PointDescription="bei D 08496 Neumark/Unterneumark " Turn="sa" SegDescription="B173" SegDist="4520" SegTime="265" TimeStamp="2005-05-06T01:01:21" ViaStation="true" Prio="0"><Point x="12,36486" y="50,65285"/></Item><Item PointDist="193518" PointDescription="in Schönfels links abbiegen auf Stenner Strasse" Turn="l" SegDescription="Stenner Strasse" SegDist="210" SegTime="44" TimeStamp="2005-05-06T01:05:46" Prio="0"><Point x="12,40865" y="50,67676"/></Item><Item PointDist="193728" PointDescription="geradeaus weiter auf Zwickauer Strasse (K9351)" Turn="sa" SegDescription="Zwickauer Strasse (K9351)" SegDist="54" SegTime="8" TimeStamp="2005-05-06T01:06:30" Prio="0"><Point x="12,40573" y="50,67636"/></Item><Item PointDist="193782" PointDescription="D 08115 Schönfels " Turn="sa" SegDescription="K9351\Zwickauer Strasse" SegDist="54" SegTime="27" TimeStamp="2005-05-06T01:06:38" ViaStation="true" Prio="0"><Point x="12,40509" y="50,67609"/></Item><Item PointDist="193836" PointDescription="halb rechts halten auf Stenner Strasse" Turn="hr" SegDescription="Stenner Strasse" SegDist="210" SegTime="38" TimeStamp="2005-05-06T01:07:05" Prio="0"><Point x="12,40573" y="50,67636"/></Item><Item PointDist="194046" PointDescription="links abbiegen auf B173 Neumarker Strasse" Turn="l" SegDescription="B173 Neumarker Strasse" SegDist="6766" SegTime="461" TimeStamp="2005-05-06T01:07:43" Prio="0"><Point x="12,40865" y="50,67676"/></Item><Item PointDist="200812" PointDescription="bei D 08056 Zwickau/Bahnhofsvorstadt " Turn="sa" SegDescription="B173\Reichenbacher Strasse" SegDist="904" SegTime="76" TimeStamp="2005-05-06T01:15:24" ViaStation="true" Prio="0"><Point x="12,47962" y="50,71357"/></Item><Item PointDist="201716" PointDescription="in Zwickau rechts abbiegen auf B173 Humboldtstrasse" Turn="r" SegDescription="B173 Humboldtstrasse" SegDist="520" SegTime="53" TimeStamp="2005-05-06T01:16:40" Prio="0"><Point x="12,48981" y="50,71823"/></Item><Item PointDist="202236" PointDescription="links abbiegen auf B173 Am Schwanenteich" Turn="l" SegDescription="B173 Am Schwanenteich" SegDist="140" SegTime="11" TimeStamp="2005-05-06T01:17:33" Prio="0"><Point x="12,49359" y="50,71426"/></Item><Item PointDist="202376" PointDescription="rechts halten auf B173 Dr.-Friedrichs-Ring" Turn="r" SegDescription="B173 Dr.-Friedrichs-Ring" SegDist="280" SegTime="20" TimeStamp="2005-05-06T01:17:44" Prio="0"><Point x="12,49542" y="50,71477"/></Item><Item PointDist="202656" PointDescription="geradeaus weiter auf B173 Glück-Auf-Brücke/Äussere Dresdner Strasse" Turn="sa" SegDescription="B173 Glück-Auf-Brücke/Äussere Dresdner Strasse" SegDist="8340" SegTime="527" TimeStamp="2005-05-06T01:18:04" Prio="0"><Point x="12,49945" y="50,71482"/></Item><Item PointDist="210996" PointDescription="rechts abbiegen auf Dresdner Strasse" Turn="r" SegDescription="Dresdner Strasse" SegDist="780" SegTime="113" TimeStamp="2005-05-06T01:26:51" Prio="0"><Point x="12,59666" y="50,74514"/></Item><Item PointDist="211776" PointDescription="geradeaus weiter auf Ã„ussere Zwickauer Strasse" Turn="sa" SegDescription="Äussere Zwickauer Strasse" SegDist="1670" SegTime="117" TimeStamp="2005-05-06T01:28:44" Prio="0"><Point x="12,6066" y="50,7471"/></Item><Item PointDist="213446" PointDescription="in Lichtenstein/Sa. geradeaus weiter auf Innere Zwickauer Strasse" Turn="sa" SegDescription="Innere Zwickauer Strasse" SegDist="327" SegTime="41" TimeStamp="2005-05-06T01:30:41" Prio="0"><Point x="12,62685" y="50,7547"/></Item><Item PointDist="213773" PointDescription="bei D 09350 Lichtenstein " Turn="sa" SegDescription="S255\Innere Zwickauer Strasse" SegDist="82" SegTime="30" TimeStamp="2005-05-06T01:31:22" ViaStation="true" Prio="0"><Point x="12,63073" y="50,75627"/></Item><Item PointDist="213855" PointDescription="rechts abbiegen auf Hartensteiner Strasse (S255)" Turn="r" SegDescription="Hartensteiner Strasse (S255)" SegDist="210" SegTime="7" TimeStamp="2005-05-06T01:31:52" Prio="0"><Point x="12,63175" y="50,75654"/></Item><Item PointDist="214065" PointDescription="rechts abbiegen auf Hartensteiner Strasse (S255)" Turn="r" SegDescription="Hartensteiner Strasse (S255)" SegDist="570" SegTime="65" TimeStamp="2005-05-06T01:31:59" Prio="0"><Point x="12,63325" y="50,75502"/></Item><Item PointDist="214635" PointDescription="rechts abbiegen auf Hartensteiner Strasse (S255)" Turn="r" SegDescription="Hartensteiner Strasse (S255)" SegDist="30" SegTime="52" TimeStamp="2005-05-06T01:33:04" Prio="0"><Point x="12,63592" y="50,75024"/></Item><Item PointDist="214665" PointDescription="halb links halten auf Hartensteiner Strasse (S255)" Turn="hl" SegDescription="Hartensteiner Strasse (S255)" SegDist="13000" SegTime="958" TimeStamp="2005-05-06T01:33:56" Prio="0"><Point x="12,6358" y="50,74998"/></Item><Item PointDist="227665" PointDescription="geradeaus weiter auf S283" Turn="sa" SegDescription="S283" SegDist="400" SegTime="92" TimeStamp="2005-05-06T01:49:54" Prio="0"><Point x="12,69692" y="50,65965"/></Item><Item PointDist="228065" PointDescription="rechts abbiegen auf S283" Turn="r" SegDescription="S283" SegDist="1900" SegTime="37" TimeStamp="2005-05-06T01:51:26" Prio="0"><Point x="12,69448" y="50,65644"/></Item><Item PointDist="229965" PointDescription="in Hartenstein links abbiegen auf August-Bebel-Strasse (S283)" Turn="l" SegDescription="August-Bebel-Strasse (S283)" SegDist="330" SegTime="37" TimeStamp="2005-05-06T01:52:03" Prio="0"><Point x="12,67448" y="50,66333"/></Item><Item PointDist="230295" PointDescription="geradeaus weiter auf Bahnhofstrasse (S284)" Turn="sa" SegDescription="Bahnhofstrasse (S284)" SegDist="6" SegTime="20" TimeStamp="2005-05-06T01:52:40" Prio="0"><Point x="12,67128" y="50,66155"/></Item><Item PointDist="230301" PointDescription="bei D 08118 Hartenstein " Turn="sa" SegDescription="S284\Bahnhofstrasse" SegDist="1189" SegTime="84" TimeStamp="2005-05-06T01:53:00" ViaStation="true" Prio="0"><Point x="12,67125" y="50,6615"/></Item><Item PointDist="231490" PointDescription="rechts abbiegen" Turn="r" SegDist="220" SegTime="24" TimeStamp="2005-05-06T01:54:24" Prio="0"><Point x="12,66372" y="50,65228"/></Item><Item PointDist="231710" PointDescription="links abbiegen" Turn="l" SegDist="130" SegTime="19" TimeStamp="2005-05-06T01:54:48" Prio="0"><Point x="12,66109" y="50,65194"/></Item><Item PointDist="231840" PointDescription="in Stein rechts abbiegen auf Langenbacher Strasse (K9309)" Turn="r" SegDescription="Langenbacher Strasse (K9309)" SegDist="130" SegTime="7" TimeStamp="2005-05-06T01:55:07" Prio="0"><Point x="12,66143" y="50,6509"/></Item><Item PointDist="231970" PointDescription="halb links halten auf Wildbacher Strasse (K9309)" Turn="hl" SegDescription="Wildbacher Strasse (K9309)" SegDist="1510" SegTime="186" TimeStamp="2005-05-06T01:55:14" Prio="0"><Point x="12,66" y="50,65024"/></Item><Item PointDist="233480" PointDescription="geradeaus weiter" Turn="sa" SegDist="180" SegTime="52" TimeStamp="2005-05-06T01:58:20" Prio="0"><Point x="12,65173" y="50,63936"/></Item><Item PointDist="233660" PointDescription="halb rechts halten auf Hartensteiner Strasse (K9109)" Turn="hr" SegDescription="Hartensteiner Strasse (K9109)" SegDist="1330" SegTime="105" TimeStamp="2005-05-06T01:59:12" Prio="0"><Point x="12,6534" y="50,6382"/></Item><Item PointDist="234990" PointDescription="in Wildbach rechts abbiegen auf Hartensteiner Strasse (K9109)" Turn="r" SegDescription="Hartensteiner Strasse (K9109)" SegDist="1840" SegTime="163" TimeStamp="2005-05-06T02:00:57" Prio="0"><Point x="12,64554" y="50,62853"/></Item><Item PointDist="236830" PointDescription="links abbiegen auf Silberbachstrasse" Turn="l" SegDescription="Silberbachstrasse" SegDist="490" SegTime="45" TimeStamp="2005-05-06T02:03:40" Prio="0"><Point x="12,64142" y="50,61336"/></Item><Item PointDist="237320" PointDescription="geradeaus weiter auf Zechenplatz " Turn="sa" SegDescription="Zechenplatz " SegDist="1670" SegTime="135" TimeStamp="2005-05-06T02:04:25" Prio="0"><Point x="12,6469" y="50,61072"/></Item><Item PointDist="238990" PointDescription="in Schlema geradeaus weiter auf Schneeberger Weg" Turn="sa" SegDescription="Schneeberger Weg" SegDist="30" SegTime="11" TimeStamp="2005-05-06T02:06:40" Prio="0"><Point x="12,65502" y="50,60139"/></Item><Item PointDist="239020" PointDescription="links abbiegen auf Zechenplatz" Turn="l" SegDescription="Zechenplatz" SegDist="60" SegTime="18" TimeStamp="2005-05-06T02:06:51" Prio="0"><Point x="12,65488" y="50,60114"/></Item><Item PointDist="239080" PointDescription="rechts abbiegen auf Friedensstrasse" Turn="r" SegDescription="Friedensstrasse" SegDist="410" SegTime="78" TimeStamp="2005-05-06T02:07:09" Prio="0"><Point x="12,65542" y="50,60074"/></Item><Item PointDist="239490" PointDescription="rechts abbiegen auf B169 Kobaltstrasse/Auer Strasse" Turn="r" SegDescription="B169 Kobaltstrasse/Auer Strasse" SegDist="1250" SegTime="105" TimeStamp="2005-05-06T02:08:27" Prio="0"><Point x="12,65089" y="50,59861"/></Item><Item PointDist="240740" PointDescription="in Schneeberg rechts abbiegen auf B169 Kobaltstrasse" Turn="r" SegDescription="B169 Kobaltstrasse" SegDist="8280" SegTime="664" TimeStamp="2005-05-06T02:10:12" Prio="0"><Point x="12,64319" y="50,58969"/></Item><Item PointDist="249020" PointDescription="in Hundshübel halb rechts halten auf B169 Hauptstrasse" Turn="hr" SegDescription="B169 Hauptstrasse" SegDist="4440" SegTime="286" TimeStamp="2005-05-06T02:21:16" Prio="0"><Point x="12,57633" y="50,54659"/></Item><Item PointDist="253460" PointDescription="in Stützengrün rechts abbiegen auf B169 Auerbacher Strasse" Turn="r" SegDescription="B169 Auerbacher Strasse" SegDist="10130" SegTime="766" TimeStamp="2005-05-06T02:26:02" Prio="0"><Point x="12,52721" y="50,53391"/></Item><Item PointDist="263590" PointDescription="in Rodewisch rechts abbiegen auf B169 Postplatz" Turn="r" SegDescription="B169 Postplatz" SegDist="170" SegTime="12" TimeStamp="2005-05-06T02:38:48" Prio="0"><Point x="12,40566" y="50,53118"/></Item><Item PointDist="263760" PointDescription="links abbiegen auf B169 Postplatz" Turn="l" SegDescription="B169 Postplatz" SegDist="544" SegTime="49" TimeStamp="2005-05-06T02:39:00" Prio="0"><Point x="12,40392" y="50,53211"/></Item><Item PointDist="264304" PointDescription="bei D 08228 Rodewisch " Turn="sa" SegDescription="B169\Lindenstrasse" SegDist="2415" SegTime="218" TimeStamp="2005-05-06T02:39:49" ViaStation="true" Prio="0"><Point x="12,40161" y="50,5289"/></Item><Item PointDist="266719" PointDescription="bei D 08209 Auerbach " Turn="sa" SegDescription="B169\Göltzschtalstrasse" SegDist="646" SegTime="58" TimeStamp="2005-05-06T02:43:27" ViaStation="true" Prio="0"><Point x="12,3979" y="50,50827"/></Item><Item PointDist="267365" PointDescription="in Auerbach/Vogtl. links abbiegen auf B169 Göltzschtalstrasse" Turn="l" SegDescription="B169 Göltzschtalstrasse" SegDist="1650" SegTime="160" TimeStamp="2005-05-06T02:44:25" Prio="0"><Point x="12,39793" y="50,50286"/></Item><Item PointDist="269015" PointDescription="in Ellefeld links abbiegen auf Neuberg" Turn="l" SegDescription="Neuberg" SegDist="250" SegTime="93" TimeStamp="2005-05-06T02:47:05" Prio="0"><Point x="12,39379" y="50,489"/></Item><Item PointDist="269265" PointDescription="rechts abbiegen auf Neuberg" Turn="r" SegDescription="Neuberg" SegDist="790" SegTime="127" TimeStamp="2005-05-06T02:48:38" Prio="0"><Point x="12,39629" y="50,4898"/></Item><Item PointDist="270055" PointDescription="rechts abbiegen auf Beerheider Strasse  (K7833)" Turn="r" SegDescription="Beerheider Strasse  (K7833)" SegDist="1410" SegTime="13" TimeStamp="2005-05-06T02:50:45" Prio="0"><Point x="12,40533" y="50,49366"/></Item><Item PointDist="271465" PointDescription="rechts abbiegen auf Beerheider Strasse (K7833)" Turn="r" SegDescription="Beerheider Strasse (K7833)" SegDist="923" SegTime="87" TimeStamp="2005-05-06T02:50:58" Prio="0"><Point x="12,42136" y="50,48718"/></Item><Item PointDist="272388" PointDescription="bei D 08209 Auerbach/Beerheide " Turn="sa" SegDescription="K7833\Rempesgrüner Strasse" SegDist="91" SegTime="30" TimeStamp="2005-05-06T02:52:25" ViaStation="true" Prio="0"><Point x="12,42487" y="50,4792"/></Item><Item PointDist="272479" PointDescription="in Beerheide links abbiegen auf Strasse des Friedens (K7826)" Turn="l" SegDescription="Strasse des Friedens (K7826)" SegDist="1040" SegTime="150" TimeStamp="2005-05-06T02:52:55" Prio="0"><Point x="12,42546" y="50,47847"/></Item><Item PointDist="273519" PointDescription="in Hohengrün rechts abbiegen auf Klingenthaler Strasse (S300)" Turn="r" SegDescription="Klingenthaler Strasse (S300)" SegDist="520" SegTime="16" TimeStamp="2005-05-06T02:55:25" Prio="0"><Point x="12,43305" y="50,48567"/></Item><Item PointDist="274039" PointDescription="links abbiegen" Turn="l" SegDist="200" SegTime="150" TimeStamp="2005-05-06T02:55:41" Prio="0"><Point x="12,43391" y="50,48116"/></Item><Item PointDist="274239" PointDescription="links abbiegen auf Schallerbachstrasse (K7822)" Turn="l" SegDescription="Schallerbachstrasse (K7822)" SegDist="2330" SegTime="45" TimeStamp="2005-05-06T02:58:11" Prio="0"><Point x="12,43586" y="50,47984"/></Item><Item PointDist="276569" PointDescription="in Brunn rechts abbiegen auf Schönheider Strasse (S278)" Turn="r" SegDescription="Schönheider Strasse (S278)" SegDist="7810" SegTime="723" TimeStamp="2005-05-06T02:58:56" Prio="0"><Point x="12,43583" y="50,50021"/></Item><Item PointDist="284379" PointDescription="in Schönheide halb rechts halten auf Hauptstrasse (S278)" Turn="hr" SegDescription="Hauptstrasse (S278)" SegDist="907" SegTime="86" TimeStamp="2005-05-06T03:10:59" Prio="0"><Point x="12,52204" y="50,50509"/></Item><Item PointDist="285286" PointDescription="D 08304 Schönheide " Turn="sa" SegDescription="S278\Hauptstrasse" SegDist="518" SegTime="72" TimeStamp="2005-05-06T03:12:25" ViaStation="true" Prio="0"><Point x="12,53336" y="50,50303"/></Item><Item PointDist="285804" PointDescription="halb links halten auf Hauptstrasse (S278)" Turn="hl" SegDescription="Hauptstrasse (S278)" SegDist="150" SegTime="18" TimeStamp="2005-05-06T03:13:37" Prio="0"><Point x="12,53994" y="50,50461"/></Item><Item PointDist="285954" PointDescription="geradeaus weiter auf Eibenstocker Strasse (S277)" Turn="sa" SegDescription="Eibenstocker Strasse (S277)" SegDist="1520" SegTime="187" TimeStamp="2005-05-06T03:13:55" Prio="0"><Point x="12,54119" y="50,50559"/></Item><Item PointDist="287474" PointDescription="rechts abbiegen auf B283 Muldenstrasse" Turn="r" SegDescription="B283 Muldenstrasse" SegDist="8880" SegTime="533" TimeStamp="2005-05-06T03:17:02" Prio="0"><Point x="12,55744" y="50,50457"/></Item><Item PointDist="296354" PointDescription="halb rechts halten auf Am Filz" Turn="hr" SegDescription="Am Filz" SegDist="860" SegTime="63" TimeStamp="2005-05-06T03:25:55" Prio="0"><Point x="12,49511" y="50,46782"/></Item><Item PointDist="297214" PointDescription="geradeaus weiter auf B283 Schönheider Strasse" Turn="sa" SegDescription="B283 Schönheider Strasse" SegDist="555" SegTime="60" TimeStamp="2005-05-06T03:26:58" Prio="0"><Point x="12,49073" y="50,46279"/></Item><Item PointDist="297769" PointDescription="bei D 08262 Tannenbergsthal/Jägersgrün " Turn="sa" SegDescription="B283\Schönheider Strasse" SegDist="3747" SegTime="225" TimeStamp="2005-05-06T03:27:58" ViaStation="true" Prio="0"><Point x="12,48844" y="50,45825"/></Item><Item PointDist="301516" PointDescription="bei D 08262 Tannenbergsthal " Turn="sa" SegDescription="B283\Klingenthaler Strasse" SegDist="7764" SegTime="548" TimeStamp="2005-05-06T03:31:43" ViaStation="true" Prio="0"><Point x="12,46112" y="50,43453"/></Item><Item PointDist="309280" PointDescription="in Klingenthal/Sa. links abbiegen auf B283 Auerbacher Strasse" Turn="l" SegDescription="B283 Auerbacher Strasse" SegDist="1410" SegTime="208" TimeStamp="2005-05-06T03:40:51" Prio="0"><Point x="12,4819" y="50,38576"/></Item><Item PointDist="310690" PointDescription="rechts abbiegen auf Mittelbergstrasse" Turn="r" SegDescription="Mittelbergstrasse" SegDist="580" SegTime="26" TimeStamp="2005-05-06T03:44:19" Prio="0"><Point x="12,47603" y="50,37537"/></Item><Item PointDist="311270" PointDescription="rechts abbiegen auf Falkensteiner Strasse (S304)" Turn="r" SegDescription="Falkensteiner Strasse (S304)" SegDist="1673" SegTime="181" TimeStamp="2005-05-06T03:44:45" Prio="0"><Point x="12,46946" y="50,37277"/></Item><Item PointDist="312943" PointDescription="bei D 08248 Klingenthal/Brunndöbra " Turn="sa" SegDescription="S304\Falkensteiner Strasse" SegDist="7942" SegTime="566" TimeStamp="2005-05-06T03:47:46" ViaStation="true" Prio="0"><Point x="12,45622" y="50,38453"/></Item><Item PointDist="320885" PointDescription="bei D 08223 Grünbach-Muldenberg " Turn="sa" SegDescription="S302/S304" SegDist="423" SegTime="2" TimeStamp="2005-05-06T03:57:12" ViaStation="true" Prio="0"><Point x="12,39973" y="50,41964"/></Item><Item PointDist="321308" PointDescription="halb links halten auf S304" Turn="hl" SegDescription="S304" SegDist="4137" SegTime="335" TimeStamp="2005-05-06T03:57:14" Prio="0"><Point x="12,39774" y="50,42322"/></Item><Item PointDist="325445" PointDescription="bei D 08223 Grünbach " Turn="sa" SegDescription="S304\Bahnhofstrasse" SegDist="399" SegTime="53" TimeStamp="2005-05-06T04:02:49" ViaStation="true" Prio="0"><Point x="12,36459" y="50,44618"/></Item><Item PointDist="325844" PointDescription="in Grünbach links abbiegen auf Neustädter Strasse (K7835)" Turn="l" SegDescription="Neustädter Strasse (K7835)" SegDist="60" SegTime="38" TimeStamp="2005-05-06T04:03:42" Prio="0"><Point x="12,36217" y="50,44933"/></Item><Item PointDist="325904" PointDescription="links abbiegen auf Siehdichfürer Strasse (K7835)" Turn="l" SegDescription="Siehdichfürer Strasse (K7835)" SegDist="2910" SegTime="245" TimeStamp="2005-05-06T04:04:20" Prio="0"><Point x="12,36146" y="50,44952"/></Item><Item PointDist="328814" PointDescription="in Neudorf links abbiegen auf Schönecker Strasse (S301)" Turn="l" SegDescription="Schönecker Strasse (S301)" SegDist="430" SegTime="50" TimeStamp="2005-05-06T04:08:25" Prio="0"><Point x="12,33196" y="50,44212"/></Item><Item PointDist="329244" PointDescription="links abbiegen auf Schönecker Strasse (S301)" Turn="l" SegDescription="Schönecker Strasse (S301)" SegDist="4465" SegTime="266" TimeStamp="2005-05-06T04:09:15" Prio="0"><Point x="12,33316" y="50,43841"/></Item><Item PointDist="333709" PointDescription="bei D 08261 Schöneck " Turn="sa" SegDescription="S301" SegDist="393" SegTime="17" TimeStamp="2005-05-06T04:13:41" ViaStation="true" Prio="0"><Point x="12,3372" y="50,40042"/></Item><Item PointDist="334102" PointDescription="in Schöneck/Vogtl. rechts abbiegen auf Falkensteiner Strasse (S301/S302)" Turn="r" SegDescription="Falkensteiner Strasse (S301/S302)" SegDist="20" SegTime="11" TimeStamp="2005-05-06T04:13:58" Prio="0"><Point x="12,33753" y="50,39691"/></Item><Item PointDist="334122" PointDescription="links abbiegen auf Albertplatz/Falkensteiner Strasse (S301/S302)" Turn="l" SegDescription="Albertplatz/Falkensteiner Strasse (S301/S302)" SegDist="630" SegTime="85" TimeStamp="2005-05-06T04:14:09" Prio="0"><Point x="12,33735" y="50,39681"/></Item><Item PointDist="334752" PointDescription="rechts abbiegen auf Klingenthaler Strasse (S301)" Turn="r" SegDescription="Klingenthaler Strasse (S301)" SegDist="600" SegTime="21" TimeStamp="2005-05-06T04:15:34" Prio="0"><Point x="12,34362" y="50,39344"/></Item><Item PointDist="335352" PointDescription="einfahren in Kreisverkehr " Turn="r" SegDist="40" SegTime="48" TimeStamp="2005-05-06T04:15:55" Prio="0"><Point x="12,3495" y="50,38969"/></Item><Item PointDist="335392" PointDescription="2. Möglichkeit aus Kreisverkehr ausfahren auf Kärnerstrasse (S305)" Turn="r" SegDescription="Kärnerstrasse (S305)" SegDist="6120" SegTime="475" TimeStamp="2005-05-06T04:16:43" Prio="0"><Point x="12,34966" y="50,38949"/></Item><Item PointDist="341512" PointDescription="rechts abbiegen auf B283" Turn="r" SegDescription="B283" SegDist="2316" SegTime="63" TimeStamp="2005-05-06T04:24:38" Prio="0"><Point x="12,37058" y="50,34307"/></Item><Item PointDist="343828" PointDescription="bei D 08258 Markneukirchen/Friebus " Turn="sa" SegDescription="B283" SegDist="4539" SegTime="342" TimeStamp="2005-05-06T04:25:41" ViaStation="true" Prio="0"><Point x="12,35151" y="50,32866"/></Item><Item PointDist="348367" PointDescription="rechts abbiegen auf B283" Turn="r" SegDescription="B283" SegDist="130" SegTime="24" TimeStamp="2005-05-06T04:31:23" Prio="0"><Point x="12,30708" y="50,30969"/></Item><Item PointDist="348497" PointDescription="in Siebenbrunn geradeaus weiter auf Am Bahnhof " Turn="sa" SegDescription="Am Bahnhof " SegDist="320" SegTime="65" TimeStamp="2005-05-06T04:31:47" Prio="0"><Point x="12,30595" y="50,30896"/></Item><Item PointDist="348817" PointDescription="links abbiegen auf Strässler Berg" Turn="l" SegDescription="Strässler Berg" SegDist="490" SegTime="121" TimeStamp="2005-05-06T04:32:52" Prio="0"><Point x="12,30217" y="50,30798"/></Item><Item PointDist="349307" PointDescription="geradeaus weiter auf Siebenbrunner Strasse" Turn="sa" SegDescription="Siebenbrunner Strasse" SegDist="680" SegTime="43" TimeStamp="2005-05-06T04:34:53" Prio="0"><Point x="12,29888" y="50,30423"/></Item><Item PointDist="349987" PointDescription="in Strässel links abbiegen auf Böhmische Strasse (K7846)" Turn="l" SegDescription="Böhmische Strasse (K7846)" SegDist="2460" SegTime="193" TimeStamp="2005-05-06T04:35:36" Prio="0"><Point x="12,29728" y="50,29896"/></Item><Item PointDist="352447" PointDescription="in Schönlind rechts abbiegen auf Markneukirchner Strasse (K7843)" Turn="r" SegDescription="Markneukirchner Strasse (K7843)" SegDist="30" SegTime="4" TimeStamp="2005-05-06T04:38:49" Prio="0"><Point x="12,31397" y="50,28425"/></Item><Item PointDist="352477" PointDescription="links abbiegen auf Landwüster Strasse (K7846)" Turn="l" SegDescription="Landwüster Strasse (K7846)" SegDist="2020" SegTime="182" TimeStamp="2005-05-06T04:38:53" Prio="0"><Point x="12,3142" y="50,28402"/></Item><Item PointDist="354497" PointDescription="in Landwüst halb rechts halten auf Schönlinder Strasse (K7844)" Turn="hr" SegDescription="Schönlinder Strasse (K7844)" SegDist="30" SegTime="4" TimeStamp="2005-05-06T04:41:55" Prio="0"><Point x="12,32864" y="50,27133"/></Item><Item PointDist="354527" PointDescription="rechts abbiegen auf Rauner Strasse (K7844)" Turn="r" SegDescription="Rauner Strasse (K7844)" SegDist="473" SegTime="199" TimeStamp="2005-05-06T04:41:59" Prio="0"><Point x="12,32848" y="50,27109"/></Item><Item PointDist="355000" PointDescription="bei D 08258 Landwüst " Turn="sa" SegDescription="K7844\Rauner Strasse" SegDist="1794" SegTime="28" TimeStamp="2005-05-06T04:45:18" ViaStation="true" Prio="0"><Point x="12,32194" y="50,27154"/></Item><Item PointDist="356794" PointDescription="geradeaus weiter auf B92/E49" Turn="sa" SegDescription="B92/E49" SegDist="5627" SegTime="395" TimeStamp="2005-05-06T04:45:46" Prio="0"><Point x="12,29975" y="50,26883"/></Item><Item PointDist="362421" PointDescription="bei D 08626 Adorf/Jugelsburg " Turn="sa" SegDescription="B92/E49" SegDist="2257" SegTime="181" TimeStamp="2005-05-06T04:52:21" ViaStation="true" Prio="0"><Point x="12,25288" y="50,30499"/></Item><Item PointDist="364678" PointDescription="bei D 08626 Adorf " Turn="sa" SegDescription="B92/E49\Oelsnitzer Strasse" SegDist="5913" SegTime="369" TimeStamp="2005-05-06T04:55:22" ViaStation="true" Prio="0"><Point x="12,25748" y="50,32437"/></Item><Item PointDist="370591" PointDescription="halb links halten" Turn="hl" SegDist="190" SegTime="43" TimeStamp="2005-05-06T05:01:31" Prio="0"><Point x="12,21624" y="50,36663"/></Item><Item PointDist="370781" PointDescription="geradeaus weiter auf B92/E49 Adorfer Strasse" Turn="sa" SegDescription="B92/E49 Adorfer Strasse" SegDist="620" SegTime="12" TimeStamp="2005-05-06T05:02:14" Prio="0"><Point x="12,21472" y="50,36786"/></Item><Item PointDist="371401" PointDescription="halb links halten" Turn="hl" SegDist="130" SegTime="18" TimeStamp="2005-05-06T05:02:26" Prio="0"><Point x="12,2089" y="50,37197"/></Item><Item PointDist="371531" PointDescription="rechts abbiegen" Turn="r" SegDist="200" SegTime="52" TimeStamp="2005-05-06T05:02:44" Prio="0"><Point x="12,20749" y="50,37262"/></Item><Item PointDist="371731" PointDescription="links abbiegen auf B92/E49 Adorfer Strasse" Turn="l" SegDescription="B92/E49 Adorfer Strasse" SegDist="5620" SegTime="338" TimeStamp="2005-05-06T05:03:36" Prio="0"><Point x="12,20676" y="50,37428"/></Item><Item PointDist="377351" PointDescription="in Oelsnitz links abbiegen auf Rosa-Luxemburg-Strasse (S311)" Turn="l" SegDescription="Rosa-Luxemburg-Strasse (S311)" SegDist="110" SegTime="19" TimeStamp="2005-05-06T05:09:14" Prio="0"><Point x="12,1735" y="50,41626"/></Item><Item PointDist="377461" PointDescription="links abbiegen auf Grabenstrasse (S311)" Turn="l" SegDescription="Grabenstrasse (S311)" SegDist="260" SegTime="34" TimeStamp="2005-05-06T05:09:33" Prio="0"><Point x="12,17221" y="50,41679"/></Item><Item PointDist="377721" PointDescription="links abbiegen auf Kirchplatz (S311)" Turn="l" SegDescription="Kirchplatz (S311)" SegDist="100" SegTime="5" TimeStamp="2005-05-06T05:10:07" Prio="0"><Point x="12,16933" y="50,41548"/></Item><Item PointDist="377821" PointDescription="rechts abbiegen auf Heppeplatz (S311)" Turn="r" SegDescription="Heppeplatz (S311)" SegDist="110" SegTime="12" TimeStamp="2005-05-06T05:10:12" Prio="0"><Point x="12,16847" y="50,41479"/></Item><Item PointDist="377931" PointDescription="links abbiegen auf Bahnhofstrasse (S307)" Turn="l" SegDescription="Bahnhofstrasse (S307)" SegDist="670" SegTime="152" TimeStamp="2005-05-06T05:10:24" Prio="0"><Point x="12,16733" y="50,41541"/></Item><Item PointDist="378601" PointDescription="rechts abbiegen auf Talsperrenstrasse (S310)" Turn="r" SegDescription="Talsperrenstrasse (S310)" SegDist="980" SegTime="244" TimeStamp="2005-05-06T05:12:56" Prio="0"><Point x="12,16149" y="50,41226"/></Item><Item PointDist="379581" PointDescription="rechts abbiegen auf Talsperrenstrasse (K7854)" Turn="r" SegDescription="Talsperrenstrasse (K7854)" SegDist="3660" SegTime="84" TimeStamp="2005-05-06T05:17:00" Prio="0"><Point x="12,14922" y="50,41313"/></Item><Item PointDist="383241" PointDescription="bei D 08606 Planschwitz " Turn="sa" SegDescription="K7854\Oelsnitzer Strasse" SegDist="50" SegTime="1" TimeStamp="2005-05-06T05:18:24" ViaStation="true" Prio="0"><Point x="12,10301" y="50,42002"/></Item><Item PointDist="383291" PointDescription="in Planschwitz links abbiegen auf Talsperrenstrasse (K7854)" Turn="l" SegDescription="Talsperrenstrasse (K7854)" SegDist="320" SegTime="85" TimeStamp="2005-05-06T05:18:25" Prio="0"><Point x="12,10234" y="50,42017"/></Item><Item PointDist="383611" PointDescription="links abbiegen" Turn="l" SegDist="2390" SegTime="194" TimeStamp="2005-05-06T05:19:50" Prio="0"><Point x="12,09876" y="50,41886"/></Item><Item PointDist="386001" PointDescription="in Bösenbrunn rechts abbiegen auf S310" Turn="r" SegDescription="S310" SegDist="540" SegTime="27" TimeStamp="2005-05-06T05:23:04" Prio="0"><Point x="12,09584" y="50,39946"/></Item><Item PointDist="386541" PointDescription="links abbiegen auf S310" Turn="l" SegDescription="S310" SegDist="2140" SegTime="150" TimeStamp="2005-05-06T05:23:31" Prio="0"><Point x="12,09108" y="50,40268"/></Item><Item PointDist="388681" PointDescription="in Dröda rechts abbiegen auf Hauptstrasse/Bobenneukirchener Strasse (S310)" Turn="r" SegDescription="Hauptstrasse/Bobenneukirchener Strasse (S310)" SegDist="70" SegTime="25" TimeStamp="2005-05-06T05:26:01" Prio="0"><Point x="12,06405" y="50,40219"/></Item><Item PointDist="388751" PointDescription="halb rechts halten auf Bobenneukirchener Strasse (S310)" Turn="hr" SegDescription="Bobenneukirchener Strasse (S310)" SegDist="206" SegTime="158" TimeStamp="2005-05-06T05:26:26" Prio="0"><Point x="12,06355" y="50,40269"/></Item><Item PointDist="388957" PointDescription="bei D 08538 Burgstein/Dröda " Turn="sa" SegDescription="S310\Bobenneukirchener Strasse" SegDist="2415" SegTime="40" TimeStamp="2005-05-06T05:29:04" ViaStation="true" Prio="0"><Point x="12,06391" y="50,40449"/></Item><Item PointDist="391372" PointDescription="in Pirk rechts abbiegen auf B173 Hofer Strasse" Turn="r" SegDescription="B173 Hofer Strasse" SegDist="440" SegTime="67" TimeStamp="2005-05-06T05:29:44" Prio="0"><Point x="12,06697" y="50,42462"/></Item><Item PointDist="391812" PointDescription="links abbiegen auf Zur Pirkmühle (K7859)" Turn="l" SegDescription="Zur Pirkmühle (K7859)" SegDist="843" SegTime="199" TimeStamp="2005-05-06T05:30:51" Prio="0"><Point x="12,07087" y="50,42752"/></Item><Item PointDist="392655" PointDescription="bei D 08538 Burgstein/Pirk " Turn="sa" SegDescription="K7859" SegDist="2818" SegTime="52" TimeStamp="2005-05-06T05:34:10" ViaStation="true" Prio="0"><Point x="12,06116" y="50,4292"/></Item><Item PointDist="395473" PointDescription="in Geilsdorf links abbiegen auf Winkel (K7859)" Turn="l" SegDescription="Winkel (K7859)" SegDist="2080" SegTime="212" TimeStamp="2005-05-06T05:35:02" Prio="0"><Point x="12,03292" y="50,42914"/></Item><Item PointDist="397553" PointDescription="in Schwand links abbiegen auf Weischlitzer Strasse (K7859)" Turn="l" SegDescription="Weischlitzer Strasse (K7859)" SegDist="220" SegTime="31" TimeStamp="2005-05-06T05:38:34" Prio="0"><Point x="12,00848" y="50,43411"/></Item><Item PointDist="397773" PointDescription="halb rechts halten auf Weischlitzer Strasse (K7859)" Turn="hr" SegDescription="Weischlitzer Strasse (K7859)" SegDist="2009" SegTime="192" TimeStamp="2005-05-06T05:39:05" Prio="0"><Point x="12,00766" y="50,43255"/></Item><Item PointDist="399782" PointDescription="bei D 08538 Burgstein/Kemnitz " Turn="sa" SegDescription="K7859" SegDist="477" SegTime="126" TimeStamp="2005-05-06T05:42:17" ViaStation="true" Prio="0"><Point x="11,98196" y="50,4299"/></Item><Item PointDist="400259" PointDescription="links abbiegen auf Kemnitzer Strasse " Turn="l" SegDescription="Kemnitzer Strasse " SegDist="1400" SegTime="20" TimeStamp="2005-05-06T05:44:23" Prio="0"><Point x="11,9765" y="50,4276"/></Item><Item PointDist="401659" PointDescription="in Krebes rechts abbiegen auf Burgsteinstrasse (K7860)" Turn="r" SegDescription="Burgsteinstrasse (K7860)" SegDist="580" SegTime="114" TimeStamp="2005-05-06T05:44:43" Prio="0"><Point x="11,98572" y="50,41839"/></Item><Item PointDist="402239" PointDescription="geradeaus weiter" Turn="sa" SegDist="880" SegTime="134" TimeStamp="2005-05-06T05:46:37" Prio="0"><Point x="11,97904" y="50,41547"/></Item><Item PointDist="403119" PointDescription="links abbiegen" Turn="l" SegDist="3170" SegTime="142" TimeStamp="2005-05-06T05:48:51" Prio="0"><Point x="11,96994" y="50,41028"/></Item><Item PointDist="406289" PointDescription="in Heinersgrün halb links halten auf An der Kapelle (K7855)" Turn="hl" SegDescription="An der Kapelle (K7855)" SegDist="1900" SegTime="300" TimeStamp="2005-05-06T05:51:13" Prio="0"><Point x="11,99692" y="50,38874"/></Item><Item PointDist="408189" PointDescription="rechts abbiegen" Turn="r" SegDist="410" SegTime="44" TimeStamp="2005-05-06T05:56:13" Prio="0"><Point x="12,01606" y="50,37803"/></Item><Item PointDist="408599" PointDescription="geradeaus weiter auf B173" Turn="sa" SegDescription="B173" SegDist="9213" SegTime="613" TimeStamp="2005-05-06T05:56:57" Prio="0"><Point x="12,01193" y="50,37553"/></Item><Item PointDist="417812" PointDescription="bei D95032 Hof " Turn="sa" SegDist="0" SegTime="0" TimeStamp="2005-05-06T06:07:10" Prio="0"><Point x="11,91306" y="50,32692"/></Item></WaypointList></TEF>\r
diff --git a/route.c b/route.c
index 0f07330877182e90ba8e7722e1a1df9e1668917f..750d139888b6ab187a1b67146ad24dabaae94351 100644 (file)
--- a/route.c
+++ b/route.c
@@ -100,6 +100,12 @@ route_add_wpt(route_head *rte, waypoint *wpt)
        ENQUEUE_TAIL(&rte->waypoint_list, &wpt->Q);
        rte->rte_waypt_ct++;    /* waypoints in this route */
        rte_waypts++;           /* total waypoints in all routes */
+       if (wpt->shortname == NULL) {
+               char tmpnam[10];
+               snprintf(tmpnam, sizeof(tmpnam), "RPT%03d",rte_waypts);
+               wpt->shortname = xstrdup(tmpnam);
+               wpt->wpt_flags.shortname_is_synthetic = 1;
+       }
 }
 
 void 
@@ -122,6 +128,10 @@ route_free(route_head *rte)
        }
        rte_waypts -= rte->rte_waypt_ct;
        waypt_flush(&rte->waypoint_list);
+        if ( rte->an1_extras ) {
+                (*(rte->an1_extras->destroy))((void *)rte->an1_extras );
+                xfree( rte->an1_extras );
+        }
        xfree(rte);
 }
 
index 23152112e2d645673039bd430c5504bf787e84a4..11dc7f29a9487aadf15968a5bca58c158dc60ed2 100644 (file)
--- a/saroute.c
+++ b/saroute.c
@@ -44,7 +44,7 @@ arglist_t saroute_args[] = {
 unsigned short
 ReadShort(FILE * f)
 {
-       unsigned short result = 0;
+       gbuint16 result = 0;
 
        fread(&result, sizeof (result), 1, f);
        return le_read16(&result);
@@ -53,7 +53,7 @@ ReadShort(FILE * f)
 unsigned long
 ReadLong(FILE * f)
 {
-       unsigned long result = 0;
+       gbuint32 result = 0;
 
        fread(&result, sizeof (result), 1, f);
        return le_read32(&result);
@@ -100,8 +100,8 @@ my_read(void)
        unsigned char *record;
        static int serial = 0;
        struct ll {
-               long lat;
-               long lon;
+               gbint32 lat;
+               gbint32 lon;
        } *latlon;
        unsigned short coordcount;
        route_head *track_head;
@@ -250,7 +250,7 @@ my_read(void)
                                }
                        }
                        if ( version > 10 ) {
-                               Skip(infile,2*sizeof(long));
+                               Skip(infile,2*sizeof(gbuint32));
                        }
                        xfree(record);
                }
@@ -270,6 +270,7 @@ wr_init(const char *fname)
 
 ff_vecs_t saroute_vecs = {
        ff_type_file,
+       { ff_cap_none, ff_cap_read, ff_cap_none},
        rd_init,
        wr_init,
        rd_deinit,
diff --git a/shape.c b/shape.c
index 0da74b97c3e34f22fde9a009be7fdfff408fe16f..cd51d232ee627957b98ddbf634a7d97da6ca64b0 100644 (file)
--- a/shape.c
+++ b/shape.c
@@ -37,8 +37,6 @@ static int nameidx;
 static void
 my_rd_init(const char *fname)
 {
-       int i;
-
        ihandle = SHPOpen(fname, "rb" );
        if (ihandle == NULL) {
                fatal(MYNAME ":Cannot open shp file %s for reading\n", fname);
@@ -100,7 +98,7 @@ my_read(void)
 void
 my_rd_deinit(void)
 {
-       close (ihandle);
+       SHPClose (ihandle);
 }
 
 void
@@ -129,7 +127,7 @@ my_write_wpt(const waypoint *wpt)
 }
 
 void
-poly_init()
+poly_init(const route_head *h)
 {
        int ct = route_waypt_count();
        polybufx = xcalloc(ct, sizeof(double));
@@ -148,7 +146,7 @@ poly_point(const waypoint *wpt)
 }
 
 void
-poly_deinit()
+poly_deinit(const route_head *h)
 {
        SHPObject *shpobject;
        shpobject = SHPCreateSimpleObject(SHPT_ARC, route_waypt_count(), 
@@ -185,16 +183,21 @@ my_write(void)
                        }
                        route_disp_all(poly_init, poly_deinit, poly_point);
                        break;
+               case rtedata:
+                       fatal(MYNAME ":Routes are not supported\n");
+                       break;
        }
 }
 
 ff_vecs_t shape_vecs = {
        ff_type_internal,
+       FF_CAP_RW_ALL,
        my_rd_init,     
        my_wr_init,     
        my_rd_deinit,
        my_wr_deinit,
        my_read,
        my_write,
+       NULL,
        NULL
 };
index d9a82d98a985c8d5f90320093cc9c08497ba4ec2..494947042c850ef68621882b248b01abdf5f0322 100644 (file)
@@ -40,27 +40,29 @@ static int  swapdepth = 0;
 static
 arglist_t stackfilt_args[] = {
        {"push", &opt_push, "Push waypoint list onto stack", NULL, 
-               ARGTYPE_BOOL},
-       {"copy", &opt_copy, "Copy waypoint list when pushing", NULL,
-               ARGTYPE_BOOL},
+               ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL},
        {"pop", &opt_pop, "Pop waypoint list from stack", NULL,
                ARGTYPE_BOOL},
-       {"append", &opt_append, "Append list when popping", NULL,
-               ARGTYPE_BOOL},
-       {"discard", &opt_discard, "Discard top of stack when popping", 
-               NULL, ARGTYPE_BOOL},
-       {"replace", &opt_replace, "Replace list with top of stack (default)", 
-               NULL, ARGTYPE_BOOL},
        {"swap", &opt_swap, "Swap waypoint list with <depth> item on stack", 
+               NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_BOOL},
+       {"copy", &opt_copy, "(push) Copy waypoint list", NULL,
+               ARGTYPE_BOOL},
+       {"append", &opt_append, "(pop) Append list", NULL,
+               ARGTYPE_BEGIN_EXCL | ARGTYPE_BOOL},
+       {"discard", &opt_discard, "(pop) Discard top of stack", 
                NULL, ARGTYPE_BOOL},
-       {"depth", &opt_depth, "Item to use when swapping", NULL, ARGTYPE_INT},
+       {"replace", &opt_replace, "(pop) Replace list (default)", 
+               NULL, ARGTYPE_END_EXCL | ARGTYPE_BOOL},
+       {"depth", &opt_depth, "(swap) Item to use (default=1)", 
+               NULL, ARGTYPE_INT},
        {"nowarn", &nowarn, "Suppress cleanup warning", NULL, 
-               ARGTYPE_INT | ARGTYPE_HIDDEN},
+               ARGTYPE_BOOL | ARGTYPE_HIDDEN},
        {0, 0, 0, 0, 0}
 };
 
 struct stack_elt {
        queue waypts;
+       unsigned int waypt_ct;
        struct stack_elt *next;
 } *stack = NULL;
 
@@ -72,11 +74,13 @@ stackfilt_process(void)
        queue *elem = NULL;
        queue *tmp = NULL;
        queue tmp_queue;
-       waypoint *wpt_tmp;
+       unsigned int tmp_count;
        
        if ( opt_push ) {
                tmp_elt = (struct stack_elt *)xmalloc(sizeof(struct stack_elt));
                QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head);
+               tmp_elt->waypt_ct = waypt_count();
+               set_waypt_count(0);
                tmp_elt->next = stack;
                stack = tmp_elt;
                if ( opt_copy ) {
@@ -101,6 +105,7 @@ stackfilt_process(void)
                else {
                        waypt_flush( &waypt_head );
                        QUEUE_MOVE(&(waypt_head), &(stack->waypts) );
+                       set_waypt_count(stack->waypt_ct);
                }
                stack = tmp_elt->next;
                xfree( tmp_elt );
@@ -117,6 +122,10 @@ stackfilt_process(void)
                QUEUE_MOVE(&tmp_queue, &(tmp_elt->waypts) );
                QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head );
                QUEUE_MOVE(&waypt_head, &tmp_queue );
+               
+               tmp_count = waypt_count();
+               set_waypt_count( tmp_elt->waypt_ct );
+               tmp_elt->waypt_ct = tmp_count;
        }
 }
 
index c5737f5b522366d0175b178494facb56d21999e7..9ee7a538a5abcd44140c15cb8a2999853f0512a1 100644 (file)
@@ -32,6 +32,7 @@ CRNEWLINE     \r\n
 TAB            \t
 SPACE                  <space>
 HASH           #
+PIPE           |
 WHITESPACE     *** SEE WHITESPACE NOTES BELOW ***
 
 WHITESPACE:
@@ -341,6 +342,14 @@ The fields used by the XCSV parser are as follows:
    
    example: IFIELD TIMET_TIME,"","%ld"
 
+ o YYYYMMDD_TIME
+   YYYYMMDD_TIME is the waypoint's creation time, if any.  It's a single
+   decimal field containing four digits of year, two digits of month, 
+   and two digits of date.   Internally it is a LONG INTEGER and thus
+   requires a LONG INTEGER printf conversion.
+
+   example: IFIELD YYYYMMDD_TIME,"","%ld"
+
  o GEOCACHE_DIFF
    GEOCACHE_DIFF is valid only for geocaches and represents a DOUBLE 
    PRECISION FLOAT.  A "three and a half star" cache would therefore be "3.5"
@@ -367,6 +376,24 @@ The fields used by the XCSV parser are as follows:
 
    example: GEOCACHE_TYPE,"","%s"
 
+ o GEOCACHE_PLACER
+   GEOCACHE_PLACER is a string containing the name of the placer of a 
+   geocache.   
+
+   example: GEOCACHE_PLACER,"","%s"
+
+ o GEOCACHE_LAST_FOUND
+   A long integer in format YYYYMMDD containing the last time this geocache
+   was found.
+
+   example: GEOCACHE_LAST_FOUND,"","%ld"
+
+ o GEOCACHE_HINT
+   The hint for this geocache.   No additional transformation (such as rot13)
+   will be performed on this string.
+
+   example: GEOCACHE_HINT,"","%s"
+
  o PATH_DISTANCE_MILES
    PATH_DISTANCE_MILES outputs the total length of the route or track from
    the start point to the current point, in miles.  This and the altitude
index 372634acb31545e84d8ae34acf8535463ae46117..3129a74fa2091ab662e2ec829565ec408768eed3 100644 (file)
@@ -1,6 +1,6 @@
 # gpsbabel XCSV style file
 #
-# Format: Delorme SA 9.0 CSV
+# Format: DeLorme SA 9.0 CSV
 # Author: Alex Mottram
 #   Date: 12/09/2002
 #
@@ -18,6 +18,10 @@ BADCHARS             COMMA
 #
 # INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
 #
-IFIELD LAT_DECIMAL, "", "%08.5f"
-IFIELD LON_DECIMAL, "", "%08.5f"
+IFIELD LAT_HUMAN_READABLE, "", "%08.5f"
+IFIELD LON_HUMAN_READABLE, "", "%08.5f"
 IFIELD DESCRIPTION, "", "%s"
+
+OFIELD LAT_DECIMAL, "", "%08.5f"
+OFIELD LON_DECIMAL, "", "%08.5f"
+OFIELD DESCRIPTION, "", "%s"
index 60da4b4eef6ea2e9b7d55f99e481a975da988463..391a96774275613179b753013749552e076a0e25 100644 (file)
 # GC171C,44.70605,-85.62265,The Michigan Frog by RealDcoy & LRB,http://www.geocaching.com/seek/cache_details.aspx?ID=5916,Traditional Cache
 #
 
-DESCRIPTION            Microsoft Streets and Trips 2002/2003
+DESCRIPTION            Microsoft Streets and Trips 2002-2005
 
 #
 # FILE LAYOUT DEFINITIIONS:
 #
-FIELD_DELIMITER                COMMA
+FIELD_DELIMITER                TAB
 RECORD_DELIMITER       NEWLINE
 BADCHARS               ,"
 
-PROLOGUE       Name,Latitude,Longitude,Name 2,URL,Type
+PROLOGUE       Name    Latitude        Longitude       Description     URL     Type    Container       Diff    Terr
 
 #
 # INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
@@ -33,4 +33,7 @@ IFIELD        LAT_DECIMAL, "", "%f"           # Latitude
 IFIELD LON_DECIMAL, "", "%f"           # Longitude
 IFIELD DESCRIPTION, "", "%s"           # Name 2 (Big Description)
 IFIELD URL, "", "%s"                   # URL
-IFIELD IGNORE, "", ""                  # Holder for Geocache Type
+IFIELD GEOCACHE_TYPE, "", "%s"         # Geocache Type
+IFIELD GEOCACHE_CONTAINER, "", "%s"    # Geocache Type
+IFIELD GEOCACHE_DIFF, "", "%3.1f"      # Geocache Type
+IFIELD GEOCACHE_TERR, "", "%3.1f"      # Geocache Type
index 6f8b07b8537e034d3c46838ebb32e28b3e522363..26f24b65bdeb76d18f9bc4ad151bc73a403573a2 100644 (file)
@@ -5,7 +5,7 @@
 #   Date: 02/22/04
 #
 
-DESCRIPTION             Delorme Street Atlas Plus
+DESCRIPTION             DeLorme Street Atlas Plus
 
 #
 # FILE LAYOUT DEFINITIIONS:
index 7176e813e2a343be25d39c18a5b89e7426ec74ac..b65b776861baa15f64710ed49c391cedf7bc04b5 100644 (file)
@@ -51,3 +51,5 @@ IFIELD  GEOCACHE_CONTAINER,"","%s"
 IFIELD  GEOCACHE_TYPE,"","%s"
 IFIELD  PATH_DISTANCE_MILES,"","%f"
 IFIELD  PATH_DISTANCE_KM, "", "%f"
+IFIELD  GEOCACHE_PLACER,"","%s"
+IFIELD  YYYYMMDD_TIME,"","%ld"
index 02bcf0c8b89ab1b8e3084b08b5b863bb014b3608..96a2246d6f3b3af664d50fb899a55f014cad5844 100644 (file)
@@ -1,6 +1,6 @@
 # gpsbabel XCSV style file
 #
-# Format: Delorme Xmap Conduit
+# Format: DeLorme Xmap Conduit
 # Author: Alex Mottram
 #   Date: 12/09/2002
 #
@@ -8,7 +8,7 @@
 # As defined in csv.c/xmap
 #
 
-DESCRIPTION            Delorme XMap HH Native .WPT
+DESCRIPTION            DeLorme XMap HH Native .WPT
 EXTENSION              wpt
 
 #
@@ -23,6 +23,10 @@ EPILOGUE     END
 #
 # INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
 #
-IFIELD LAT_DECIMAL, "", "%08.5f"
-IFIELD LON_DECIMAL, "", "%08.5f"
+IFIELD LAT_HUMAN_READABLE, "", "%08.5f"
+IFIELD LON_HUMAN_READABLE, "", "%08.5f"
 IFIELD DESCRIPTION, "", "%s"
+
+OFIELD LAT_DECIMAL, "", "%08.5f"
+OFIELD LON_DECIMAL, "", "%08.5f"
+OFIELD DESCRIPTION, "", "%s"
index 270ad96ee2652c441fb94612899ce37cca5b75e0..f6dd56337b9e9c7e1d9fa3f06a910782aeb08f74 100644 (file)
@@ -1,11 +1,11 @@
 # gpsbabel XCSV style file
 #
-# Format: Delorme Xmap HH Street Atlas USA .WPT (PocketPC)
+# Format: DeLorme Xmap HH Street Atlas USA .WPT (PocketPC)
 # Author: Alex Mottram
 #   Date: 12/09/2002
 #
 # 
-DESCRIPTION            Delorme XMat HH Street Atlas USA .WPT (PPC)
+DESCRIPTION            DeLorme XMat HH Street Atlas USA .WPT (PPC)
 SHORTLEN               32
 SHORTWHITE             0
 
diff --git a/tef_xml.c b/tef_xml.c
new file mode 100644 (file)
index 0000000..a5e2ac6
--- /dev/null
+++ b/tef_xml.c
@@ -0,0 +1,308 @@
+/* 
+       Support for XML based "TourExchangeFormat", 
+       found in Map & Guide Motorrad-Tourenplaner 2005/06
+       
+       Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de
+
+       Based on kml.c, Keyhole "kml" format.
+       Copyright (C) 2005 Robert Lipe, robertlipe@usa.net
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+*/
+
+#include "defs.h"
+#include "xmlgeneric.h"
+
+static char *deficon = NULL;
+
+static waypoint *wpt_tmp = NULL;
+static int item_count = -1;
+static int waypoints = 0;
+
+static route_head *route = NULL;
+
+FILE *fd;
+FILE *ofd;
+
+static char *routevia = NULL;
+
+static arglist_t tef_xml_args[] = 
+{
+       {"routevia", &routevia, "Include only via stations in route", NULL, ARGTYPE_BOOL},
+       {0, 0, 0, 0 }
+};
+
+#define MYNAME "TourExchangeFormat"
+
+#if NO_EXPAT
+void
+tef_xml_rd_init(const char *fname)
+{
+       fatal(MYNAME ": This build excluded TEF support because expat was not installed.\n");
+}
+
+void
+tef_xml_read(void)
+{
+}
+
+#else
+
+static xg_callback     tef_start, tef_header, tef_list_start, tef_list_end;
+static xg_callback     tef_item_start, tef_point, tef_item_end;
+
+static 
+xg_tag_mapping tef_xml_map[] = {
+       { tef_start,            cb_start,       "/TEF" },
+       { tef_header,           cb_start,       "/TEF/Header" },
+       { tef_list_start,       cb_start,       "/TEF/WaypointList" },
+       { tef_item_start,       cb_start,       "/TEF/WaypointList/Item" },
+       { tef_point,            cb_start,       "/TEF/WaypointList/Item/Point" },
+       { tef_item_end,         cb_end,         "/TEF/WaypointList/Item" },
+       { tef_list_end,         cb_end,         "/TEF/WaypointList" },
+       { NULL,                 0,              NULL }
+};
+
+
+/*
+ * tef_start: check for comment "TourExchangeFormat"
+ */
+
+void 
+tef_start(const char *args, const char **attrv)
+{
+       int valid = 0;
+       const char **avp = &attrv[0];
+        while (*avp) 
+       {
+           if (strcmp(avp[0], "Comment") == 0) 
+           {
+               if (0 == strcmp(avp[1], "TourExchangeFormat")) valid = 1;
+           }
+           avp+=2;
+        }
+       if (!valid)
+       {
+           fatal(MYNAME ": error in source file.\n");
+       }
+}
+
+/*
+ * tef_header: "Name" > Route name, "Software" > Route descr.
+ */
+
+void 
+tef_header(const char *args, const char **attrv)
+{
+       const char **avp = &attrv[0];
+
+       if (global_opts.objective == rtedata)
+       {
+           route = route_head_alloc();
+           while (*avp) 
+           {
+               if (strcmp(avp[0], "Name") == 0) 
+               {
+                   route->rte_name = str_utf8_to_cp1252(avp[1]);
+               }
+               else if (strcmp(avp[0], "Software") == 0) 
+               {
+                   route->rte_desc = str_utf8_to_cp1252(avp[1]);
+               }
+               avp+=2;
+           }
+           route_add_head(route);
+       }
+}
+
+/*
+ *
+ */
+void
+tef_list_start(const char *args, const char **attrv)
+{
+       const char **avp = &attrv[0];
+
+        while (*avp) 
+       {
+           if (strcmp(avp[0], "ItemCount") == 0) 
+           {
+               sscanf(avp[1], "%d", &item_count);
+           }
+            avp+=2;
+        }
+}
+
+/*
+ * local procedure for waypoint handling
+ */
+void waypoint_final()
+{
+       int via;
+       if (wpt_tmp == NULL) return;
+
+       via = wpt_tmp->centiseconds;
+       wpt_tmp->centiseconds = 0;
+       
+       if (via != 0)
+           waypt_add(wpt_tmp);
+           
+       if (route != NULL)
+       {
+           if ((via != 0) || (routevia == NULL))
+           {
+               waypoint *wpt = waypt_dupe(wpt_tmp);
+               route_add_wpt(route, wpt);
+           }
+       }
+       
+       if (via == 0)
+           waypt_free(wpt_tmp);
+           
+       wpt_tmp = NULL;
+}
+
+void 
+tef_item_end(const char *args, const char **unused)
+{
+       waypoint_final();
+}
+
+/*
+ * 
+ */
+void 
+tef_list_end(const char *args, const char **unused)
+{
+       waypoint_final();
+       if (waypoints != item_count)
+       {
+           fatal(MYNAME ": waypoint count differs to internal \"ItemCount\"! (%d to %d)\n", waypoints, item_count);
+       }
+}
+
+/*
+ * 
+ */
+void 
+tef_item_start(const char *args, const char **attrv)
+{
+       const char **avp = &attrv[0];
+
+       wpt_tmp = waypt_new();
+       wpt_tmp->centiseconds = 0;
+       
+       if ((waypoints == 1) || (waypoints == item_count)) 
+           wpt_tmp->centiseconds++;
+           
+       waypoints++;
+       
+       while (*avp) 
+       {
+           if (0 == strcmp(avp[0], "PointDescription")) 
+           {
+               wpt_tmp->shortname = str_utf8_to_cp1252(avp[1]);
+           }
+           if (0 == strcmp(avp[0], "SegDescription")) 
+           {
+               wpt_tmp->description = str_utf8_to_cp1252(avp[1]);
+           }
+           if ((0 == strcmp(avp[0], "ViaStation")) && (0 == strcmp(avp[1], "true")))
+           {
+               wpt_tmp->centiseconds = 1;
+           }
+           avp+=2;
+       }
+}
+
+/*
+ * 
+ */
+void 
+tef_point(const char *args, const char **attrv)
+{
+        const char **avp = &attrv[0];
+       char *comma;
+
+       if (!wpt_tmp) return;
+       
+        while (*avp) 
+       {
+           if (strcmp(avp[0], "y") == 0) 
+           {
+               comma = strstr(avp[1], ",");
+               if (comma) *comma='.';
+                sscanf(avp[1], "%lf", &wpt_tmp->latitude);
+           }
+           else if (strcmp(avp[0], "x") == 0) 
+           {
+               comma = strstr(avp[1], ",");
+               if (comma) *comma='.';
+               sscanf(avp[1], "%lf", &wpt_tmp->longitude);
+           }
+            avp+=2;
+        }
+}
+
+/*
+ * 
+ */
+static void 
+tef_xml_rd_init(const char *fname)
+{
+       xml_init(fname, tef_xml_map);
+}
+
+/*
+ * 
+ */
+static void 
+tef_xml_read(void)
+{
+       xml_read();
+}
+
+#endif
+
+/*
+ * 
+ */
+void 
+tef_xml_rd_deinit(void)
+{
+       xml_deinit();
+}
+
+ff_vecs_t tef_xml_vecs = {
+       ff_type_file,
+       { ff_cap_none, ff_cap_none, ff_cap_read },
+       tef_xml_rd_init,        
+       NULL,   
+       tef_xml_rd_deinit,
+       NULL,
+       tef_xml_read,
+       NULL,
+       NULL, 
+       tef_xml_args
+};
diff --git a/testo b/testo
index cba457c9aa3696e643b44650697a003738fabbd6..7b931e87b0535f90db6946754eb6b6b0088bdb31 100644 (file)
--- a/testo
+++ b/testo
@@ -80,6 +80,19 @@ ${PNAME} -i geo -f geocaching.loc -o tiger -F ${TMPDIR}/tiger
 ${PNAME} -i tiger -f ${TMPDIR}/tiger -o tiger -F ${TMPDIR}/tiger2
 compare ${TMPDIR}/tiger ${TMPDIR}/tiger2
 
+#
+# Lowrance USR.  Binary, and also slightly lossy because of the math to
+# convert lat/long.  It also doesn't support description, which makes it
+# awkward  to test.
+#
+rm -f ${TMPDIR}/lowrance1.usr
+${PNAME} -i geo -f geocaching.loc -o lowranceusr -F ${TMPDIR}/lowrance1.usr
+bincompare ${TMPDIR}/lowrance1.usr reference/lowrance.usr
+${PNAME} -i lowranceusr -f ${TMPDIR}/lowrance1.usr -o lowranceusr -F ${TMPDIR}/lowrance1.usr
+# And because of the FP rounding, we can't even read our file, write it back
+# and get the same data.  Sigh. 
+# bincompare reference/lowrance.usr  ${TMPDIR}/lowrance1.usr
+
 # CSV (Comma separated value) data.
 
 ${PNAME}  -i geo -f geocaching.loc -o csv -F ${TMPDIR}/csv.csv
@@ -156,7 +169,7 @@ compare ${TMPDIR}/ozi.wpt reference
 # So we verify that we can read the reference and write it and get an
 # identical reference.
 ${PNAME} -i holux -f reference/paris.wpo -o holux -F ${TMPDIR}/paris.wpo
-compare reference/paris.wpo ${TMPDIR}/paris.wpo
+compare reference/paris.wpo ${TMPDIR}/paris.wpo
 
 # Magellan NAV Companion for PalmOS
 # This format is hard to test, because each record and the database itself
@@ -401,6 +414,18 @@ ${PNAME} -i navicache -f reference/navicache.xml -o gpsutil -F ${TMPDIR}/navi.wp
 compare ${TMPDIR}/navi.wpt reference/navicache.ref
 #
 
+#
+# CoastalExplorer..
+${PNAME} -r -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx
+compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref
+${PNAME} -r -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob
+compare ${TMPDIR}/coastexp.nob reference/coastexp.ref2
+${PNAME} -w -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx
+compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref3
+${PNAME} -w -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob
+compare ${TMPDIR}/coastexp.nob reference/coastexp.ref4
+#
+
 # PsiTrex.  A text format that can't be handled by XCSV due to context of
 # data based on other data values in the file
 # Waypoints first
@@ -556,6 +581,51 @@ compare ${TMPDIR}/igc_sed.out reference/igc2_igc.out
 ${PNAME} -i igc -f ${TMPDIR}/igc.out -o gpx -F ${TMPDIR}/igc.gpx
 compare ${TMPDIR}/igc.gpx reference/igc2_gpx.out
 
+#
+# Google Maps XML test
+#
+rm -f ${TMPDIR}/google.out
+${PNAME} -i google -f reference/google.xml -o arc -F ${TMPDIR}/google.out
+compare ${TMPDIR}/google.out reference/google.arc
+
+rm -f ${TMPDIR}/google.out
+${PNAME} -i google -f reference/google.js -o arc -F ${TMPDIR}/google.out
+compare ${TMPDIR}/google.out reference/google.arc
+
+#
+# DeLorme .an1 tests
+#
+rm -f ${TMPDIR}/an1.out
+${PNAME} -i an1 -f reference/foo.an1 -o csv -F ${TMPDIR}/an1.out
+compare ${TMPDIR}/an1.out reference/an1-in.ref
+
+rm -f ${TMPDIR}/an1.out
+${PNAME} -i an1 -f reference/foo.an1 -o an1 -F ${TMPDIR}/an1.out
+compare ${TMPDIR}/an1.out reference/an1-an1.ref
+
+rm -f ${TMPDIR}/an1.out
+${PNAME} -i xmap -f reference/xmap -o an1 -F ${TMPDIR}/an1.out 
+compare ${TMPDIR}/an1.out reference/an1-out.ref
+
+rm -f ${TMPDIR}/an1.out
+${PNAME} -i google -f reference/google.js -o an1 -F ${TMPDIR}/an1.out
+compare ${TMPDIR}/an1.out reference/an1-line-out.ref
+
+#
+# TomTom .ov2 tests
+#
+
+rm -f ${TMPDIR}/ov2.out
+${PNAME} -i arc -f reference/google.arc -o tomtom -F ${TMPDIR}/ov2.out
+compare ${TMPDIR}/ov2.out reference/ov2-arc-out.ref
+
+rm -f ${TMPDIR}/ov2.out
+${PNAME} -i geo -f reference/gl.loc -o tomtom -F ${TMPDIR}/ov2.out
+compare ${TMPDIR}/ov2.out reference/ov2-geo-out.ref
+
+rm -f ${TMPDIR}/ov2.out
+${PNAME} -i tomtom -f reference/ov2-geo-out.ref -o gpsutil -F ${TMPDIR}/ov2.out
+compare ${TMPDIR}/ov2.out reference/ov2-in.ref
 
 #
 # XCSV "human readable" tests
@@ -596,4 +666,45 @@ ${PNAME} -i hsandv -f reference/Glad_4.exp -o hsandv -F ${TMPDIR}/Glad_5.exp
 
 ${PNAME} -i geo -f geocaching.loc -x stack,push,copy,nowarn -x stack,push,copy -x stack,push -x stack,pop,replace -x stack,pop,append -x stack,push,copy -x stack,pop,discard -x stack,swap,depth=1 -o arc -F ${TMPDIR}/stackfilt.txt
 
+#
+# 'tabsep' isn't really tested in any non-trivial way, but we do exercise
+# it.
+#
+
+${PNAME} -i geo -f geocaching.loc  -o tabsep -F - | ${PNAME} -i tabsep -f - -o geo -F ${TMPDIR}/tabsep.out
+${PNAME} -i geo -f geocaching.loc  -o geo -F ${TMPDIR}/geotabsep.out
+
+# 
+# Now do the same for custom - it has the same issues.
+#
+
+compare ${TMPDIR}/tabsep.out ${TMPDIR}/geotabsep.out
+${PNAME} -i geo -f geocaching.loc  -o custom -F - | ${PNAME} -i custom -f - -o geo -F ${TMPDIR}/custom.out
+${PNAME} -i geo -f geocaching.loc  -o geo -F ${TMPDIR}/geocustom.out
+
+#
+# Write something to the various output-only formats
+#
+${PNAME} -i geo -f geocaching.loc -o text -F ${TMPDIR}/text.out -o html -F ${TMPDIR}/html.out -o vcard -F ${TMPDIR}/vcard.out #-o palmdoc -F ${TMPDIR}/pd.out
+
+#
+# TourExchangeFormat tef (read only)
+#
+rm -f ${TMPDIR}/tef_xml*
+${PNAME} -r -i tef -f reference/route/tef_xml.sample.xml -o gpx -F ${TMPDIR}/tef_xml.sample.gpx
+grep -v "<time>" reference/route/tef_xml.sample.gpx > ${TMPDIR}/tef_xml.sample.gpx.ref
+grep -v "<time>" ${TMPDIR}/tef_xml.sample.gpx > ${TMPDIR}/tef_xml.sample.gpx.new
+compare ${TMPDIR}/tef_xml.sample.gpx.ref ${TMPDIR}/tef_xml.sample.gpx.new
+
+#
+# PathAway Palm Database .pdb tests
+#
+rm -f ${TMPDIR}/pathaway*
+${PNAME} -i geo -f geocaching.loc -o pathaway,dbname="pathaway-geo" -F ${TMPDIR}/pathaway-geo.pdb
+${PNAME} -i pathaway -f ${TMPDIR}/pathaway-geo.pdb -o geo -F ${TMPDIR}/pathaway-geo.loc
+compare ${TMPDIR}/pathaway-geo.loc reference/pathaway-geo.loc
+rm -f ${TMPDIR}/pathaway*
+${PNAME} -t -i pathaway -f reference/track/pathaway.pdb -o gpx -F ${TMPDIR}/pathaway.gpx
+compare ${TMPDIR}/pathaway.gpx reference/track/pathaway.gpx
+
 exit 0
diff --git a/text.c b/text.c
index b369e75002055a24640a9bf6d355c6d811c19303..56b272c76e2c664790fb90b60a29a0fbada74eca 100644 (file)
--- a/text.c
+++ b/text.c
@@ -67,12 +67,12 @@ text_disp(const waypoint *wpt)
        int latint, lonint;
        char tbuf[1024];
        time_t tm = wpt->creation_time;
-       long utmz;
+       int32 utmz;
        double utme, utmn;
        char utmzc;
        
-       lonint = abs(wpt->longitude);
-       latint = abs(wpt->latitude);
+       lonint = abs((int) wpt->longitude);
+       latint = abs((int) wpt->latitude);
 
        GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, 
                &utme, &utmn, &utmz, &utmzc);
@@ -82,7 +82,7 @@ text_disp(const waypoint *wpt)
        strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm));
 
        fprintf(file_out, "%-16s  %c%d %06.3f  %c%d %06.3f  (%ld%c %6.0f %7.0f)",
-               (global_opts.synthesize_shortnames) ? mkshort(mkshort_handle, wpt->description) : wpt->shortname,
+               (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname,
                wpt->latitude < 0 ? 'S' : 'N',  abs(latint), 60.0 * (fabs(wpt->latitude) - latint), 
                wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint),
                utmz, utmzc, utme, utmn);
@@ -220,6 +220,7 @@ data_write(void)
 
 ff_vecs_t text_vecs = {
        ff_type_file,
+       { ff_cap_write, ff_cap_none, ff_cap_none},
        NULL,
        wr_init,
        NULL,
diff --git a/tiger.c b/tiger.c
index e0fdfd4f10e2ee376075dbd3cfbdbfdda584b77b..b00699f0dd51284ddc7f3e8c0efb853d7f62f864 100644 (file)
--- a/tiger.c
+++ b/tiger.c
@@ -136,7 +136,7 @@ data_read(void)
        while (fgets(ibuf, sizeof(ibuf), file_in)) {
                if( sscanf(ibuf, "%lf,%lf:%100[^:]:%100[^\n]", 
                                &lon, &lat, icon, desc)) {
-                       wpt_tmp = xcalloc(sizeof (*wpt_tmp), 1);
+                       wpt_tmp = waypt_new();
 
                        wpt_tmp->longitude = lon;
                        wpt_tmp->latitude = lat;
@@ -277,6 +277,7 @@ data_write(void)
 
 ff_vecs_t tiger_vecs = {
        ff_type_file, 
+       FF_CAP_RW_WPT,
        rd_init,
        wr_init,
        rd_deinit,
diff --git a/tmpro.c b/tmpro.c
index e9968814d9539dd72ee9b7cd0f15561f033e1678..4940f20cc0c7e5c02f0253052082769cec3ddbf6 100644 (file)
--- a/tmpro.c
+++ b/tmpro.c
@@ -84,7 +84,7 @@ data_read(void)
        /* skip the line if it contains "sHyperLink" as it is a header (I hope :) */
        if ((strlen(buff)) && (strstr(buff, "sHyperLink") == NULL)) {
 
-           wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1);
+           wpt_tmp = waypt_new();
 
            /* data delimited by tabs, not enclosed in quotes.  */
            s = buff;
@@ -180,7 +180,7 @@ tmpro_waypt_pr(const waypoint * wpt)
        if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) {
         if (wpt->description) {
             if (global_opts.synthesize_shortnames)
-                shortname = mkshort(mkshort_handle, wpt->description);
+                shortname = mkshort_from_wpt(mkshort_handle, wpt);
             else
                 shortname = csv_stringclean(wpt->description, ",\"");
         } else {
@@ -244,6 +244,7 @@ data_write(void)
 
 ff_vecs_t tmpro_vecs = {
     ff_type_file,
+    FF_CAP_RW_WPT,
     rd_init,
     wr_init,
     rd_deinit,
diff --git a/tomtom.c b/tomtom.c
new file mode 100644 (file)
index 0000000..ce75fb5
--- /dev/null
+++ b/tomtom.c
@@ -0,0 +1,343 @@
+/*
+    Read and write TomTom .ov2 files.
+
+    Copyright (C) 2005  Ronald Parker (babeltomtom@parkrrrr.com) and
+                        Robert Lipe (robertlipe@usa.net)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+
+/*
+    This module is based on my reverse-engineering of the .ov2 format, so
+    it might not be aware of all record types.  In particular, I've seen 
+    a type-3 record that may contain additional strings, but since I haven't
+    seen any of those from a legitimate source, I don't know what they are
+    supposed to contain.  Thus, they are not currently supported.  (The one
+    I saw was due to an errant pair of double-quotes in the input to
+    makeov2.exe.)   -- Ron Parker, 28 April 2005
+*/
+   
+
+#include "defs.h"
+
+#define MYNAME "TomTom"
+
+static FILE *file_in;
+static FILE *file_out;
+
+static
+arglist_t tomtom_args[] = {
+       {0, 0, 0, 0 }
+};
+
+static void
+rd_init(const char *fname)
+{
+       file_in = xfopen(fname, "rb", MYNAME);
+}
+
+static void
+rd_deinit(void)
+{
+       fclose(file_in);
+}
+
+static void
+wr_init(const char *fname)
+{
+       file_out = xfopen(fname, "wb", MYNAME);
+}
+
+static void
+wr_deinit(void)
+{
+       fclose(file_out);
+}
+
+static unsigned long
+read_long(FILE * f)
+{
+        gbuint32 result = 0;
+       
+        fread(&result, sizeof (result), 1, f);
+        return le_read32(&result);
+}
+
+static unsigned char
+read_char( FILE *f)
+{
+       unsigned char result = 0;
+       fread( &result, 1, 1, f );
+       return result;
+}
+
+static void
+data_read(void)
+{
+       unsigned char rectype;
+       long recsize;
+       long x;
+       long y;
+       char *desc;
+       waypoint *wpt_tmp;
+       while (!feof( file_in ) ) {
+               rectype = read_char( file_in );
+               if ( rectype == 1 ) {
+                       /* a block header; ignored on read */
+                       read_long( file_in );
+                       read_long( file_in );
+                       read_long( file_in );
+                       read_long( file_in );
+                       read_long( file_in );
+               }
+               else if ( rectype == 2 ) {
+                       recsize = read_long( file_in );
+                       x = read_long( file_in );
+                       y = read_long( file_in );
+                       desc = (char *)xmalloc( recsize - 13 );
+                       fread( desc, recsize-13, 1, file_in );
+                       
+                       wpt_tmp = waypt_new();
+
+                       wpt_tmp->longitude = x/100000.0;
+                       wpt_tmp->latitude = y/100000.0;
+                       wpt_tmp->description = desc;
+
+                       waypt_add(wpt_tmp);
+               }
+       }
+}
+
+
+struct hdr{
+       waypoint *wpt;
+};
+
+static
+int 
+compare_lat(const void *a, const void *b)
+{
+       const struct hdr *wa = a;
+       const struct hdr *wb = b;
+
+        double difference = wa->wpt->latitude - wb->wpt->latitude;
+       if ( difference < 0 ) {
+               return -1;
+       }
+       if ( difference ) {
+               return 1;
+       }
+       return 0;
+}
+
+static
+int 
+compare_lon(const void *a, const void *b)
+{
+       const struct hdr *wa = a;
+       const struct hdr *wb = b;
+
+        double difference = wa->wpt->longitude - wb->wpt->longitude;
+       if ( difference < 0 ) {
+               return -1;
+       }
+       if ( difference ) {
+               return 1;
+       }
+       return 0;
+}
+
+static void 
+write_long( FILE *file, long value ) {
+        gbuint32 tmp = 0;
+        le_write32( &tmp, value );
+                
+        fwrite( &tmp, sizeof(tmp), 1, file );
+} 
+
+static void
+write_float_as_long( FILE *file, double value ) 
+{
+       long tmp = (value + 0.500000000001);
+       write_long( file, tmp);
+}
+
+static void
+write_char( FILE *file, unsigned char value ) {
+       fwrite( &value, 1, 1, file );
+}
+
+static void
+write_string( FILE *file, char *str ) {
+       fwrite( str, strlen(str), 1, file );
+       write_char( file, '\0' );
+}
+
+struct blockheader {
+       struct hdr *start;
+       long count;
+       long size;
+       double minlat;
+       double maxlat;
+       double minlon; 
+       double maxlon;
+       struct blockheader *ch1;
+       struct blockheader *ch2;
+};
+
+static void
+write_blocks( FILE *f, struct blockheader *blocks ) {
+       int i;
+       write_char( f, 1 );
+       write_long( f, blocks->size );
+       write_float_as_long( f, blocks->maxlon*100000 );
+       write_float_as_long( f, blocks->maxlat*100000 );
+       write_float_as_long( f, blocks->minlon*100000 );
+       write_float_as_long( f, blocks->minlat*100000 );
+       if ( blocks->ch1 ) {
+               write_blocks( f, blocks->ch1 );
+       }
+       if ( blocks->ch2 ) {
+               write_blocks( f, blocks->ch2 );
+       }
+       if ( !blocks->ch1 && !blocks->ch2 ) {
+               for ( i = 0; i < blocks->count; i++ ) {
+                       write_char( f, 2 );
+                       write_long( f, strlen( blocks->start[i].wpt->description ) + 14 );
+                       write_float_as_long( f, blocks->start[i].wpt->longitude*100000);
+                       write_float_as_long( f, blocks->start[i].wpt->latitude*100000);
+                       write_string( f, blocks->start[i].wpt->description);
+               }
+       }
+}      
+
+static struct blockheader *
+compute_blocks( struct hdr *start, int count,
+            double minlon, double maxlon, double minlat, double maxlat ) {
+       struct blockheader *newblock;
+       
+       newblock = (struct blockheader *)xcalloc( sizeof( *newblock ), 1);
+       newblock->start = start;
+       newblock->count = count;
+       newblock->minlon = minlon;
+       newblock->maxlon = maxlon;
+       newblock->minlat = minlat;
+       newblock->maxlat = maxlat;
+       newblock->size = 4 * 5 + 1;   /* hdr is 5 longs, 1 char */
+       if ( count < 20 ) {
+               int i;
+               waypoint *wpt = NULL;
+
+               for ( i = 0; i < count; i++ ) {
+                       newblock->size += 4 * 3 + 1;  
+                               /* wpt const part 3 longs, 1 char */
+                       wpt = start[i].wpt;
+                       newblock->size += strlen( wpt->description ) + 1;
+               }       
+       }
+       else {
+               if ( (maxlat-minlat)>(maxlon-minlon)) {
+                       /* split along lats */
+                       qsort( start, count, sizeof(*start), compare_lat);
+                       newblock->ch1 = compute_blocks( start, count/2,
+                               minlon, maxlon, minlat, 
+                               start[count/2].wpt->latitude );
+                       newblock->ch2 = compute_blocks( start+count/2, 
+                               count-count/2, minlon, maxlon,
+                               start[count/2].wpt->latitude, maxlat );
+               }       
+               else {
+                       /* split along lons */
+                       qsort( start, count, sizeof(*start), compare_lon);
+                       newblock->ch1 = compute_blocks( start, count/2,
+                               minlon, start[count/2].wpt->longitude, 
+                               minlat, maxlat );
+                       newblock->ch2 = compute_blocks( start+count/2, 
+                               count-count/2, start[count/2].wpt->longitude, 
+                               maxlon, minlat, maxlat );
+               }
+               if ( newblock->ch1 ) {
+                       newblock->size += newblock->ch1->size;
+               }
+               if ( newblock->ch2 ) {
+                       newblock->size += newblock->ch2->size;
+               }
+       }
+       return newblock;
+}
+
+static void
+free_blocks( struct blockheader *block ) {
+       if ( block->ch1 ) free_blocks( block->ch1 );
+       if ( block->ch2 ) free_blocks( block->ch2 );
+       xfree( block );
+}
+
+static void
+data_write(void)
+{
+       int ct = waypt_count();
+       struct hdr *htable, *bh;
+        queue *elem, *tmp;
+       extern queue waypt_head;
+        waypoint *waypointp;
+       double minlon = 200;
+       double maxlon = -200;
+       double minlat = 200;
+       double maxlat = -200;
+       struct blockheader *blocks = NULL;
+
+       htable = xmalloc(ct * sizeof(*htable));
+       bh = htable;
+
+        QUEUE_FOR_EACH(&waypt_head, elem, tmp) {
+           waypointp = (waypoint *) elem;
+           bh->wpt = waypointp;
+           if ( waypointp->longitude > maxlon ) {
+                   maxlon = waypointp->longitude;
+           }
+           if ( waypointp->longitude < minlon ) {
+                   minlon = waypointp->longitude;
+           }
+           if ( waypointp->latitude > maxlat ) {
+                   maxlat = waypointp->latitude;
+           }
+           if ( waypointp->latitude < minlat ) {
+                   minlat = waypointp->latitude;
+           }
+           bh ++;
+       }
+
+       blocks = compute_blocks( htable, ct, minlon, maxlon, minlat, maxlat );
+       write_blocks( file_out, blocks );
+       free_blocks( blocks );
+       
+       xfree(htable);
+}
+
+ff_vecs_t tomtom_vecs = {
+       ff_type_file,
+       FF_CAP_RW_WPT,
+       rd_init,
+       wr_init,
+       rd_deinit,
+       wr_deinit,
+       data_read,
+       data_write,
+       NULL,
+       tomtom_args,
+};
index 3a50da20a7496961d31a6507eea70161a152a4e8..87487994496124fd848b17a6b9a39d3d8de9fdaf 100644 (file)
@@ -9,6 +9,9 @@ sub alloc {
         ($ofile,$oline) = @{$arena{$addr}};
         print( "duplicate allocation $addr at $file $line\n  allocated at $ofile $oline\n" );
     }
+    if ( $freed{$addr} ) {
+       delete $freed{$addr};
+    }
     $arena{$addr} = [$file,$line];
 }
 
index ed3b9ec5f86928d22179ef553e98608ef1ada4d3..5df969a82b4e3d8bcce9eaa87d2904bd545910ae 100644 (file)
@@ -1,3 +1,4 @@
+# cvsps -u
 cvsps $* |  awk '
 /^Date:/ { 
        logt = "";
diff --git a/tpg.c b/tpg.c
index d9eb11c7c5d00a364865a3e05ebb1332f18b1186..c30dec2554945b27c4aae90ffd811acf27afea30 100644 (file)
--- a/tpg.c
+++ b/tpg.c
@@ -22,6 +22,7 @@
 
 #include "defs.h"
 #include <string.h>
+#include <ctype.h>
 #include "jeeps/gpsmath.h" /* for datum conversions */
 
 #define MYNAME "TPG"
@@ -134,7 +135,7 @@ tpg_read(void)
         
         
        while (pointcount--) {
-           wpt_tmp = xcalloc(sizeof(*wpt_tmp),1);
+           wpt_tmp = waypt_new();
 
             /* 1 bytes at start of record - string size for shortname */
            tpg_fread(&buff[0], 1, 1, tpg_file_in);
@@ -224,7 +225,7 @@ tpg_waypt_pr(const waypoint *wpt)
         if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) {
             if (wpt->description) {
                 if (global_opts.synthesize_shortnames)
-                    shortname = mkshort(mkshort_handle, wpt->description);
+                    shortname = mkshort_from_wpt(mkshort_handle, wpt);
                 else
                     shortname = xstrdup(wpt->description);
             } else {
@@ -355,6 +356,7 @@ tpg_write(void)
 
 ff_vecs_t tpg_vecs = {
        ff_type_file,
+       FF_CAP_RW_WPT,
        tpg_rd_init,
        tpg_wr_init,
        tpg_rd_deinit,
diff --git a/util.c b/util.c
index 975b7598fe83f955844d98c45086cc34c173aac1..4ce40cf4fbdfd8e712d54348b91517d91c5a51b2 100644 (file)
--- a/util.c
+++ b/util.c
@@ -121,7 +121,7 @@ XSTRDUP(const char *s, DEBUG_PARAMS )
 xstrdup(const char *s)
 #endif
 {
-       char *o = strdup(s);
+       char *o = s ? strdup(s) : strdup("");
 #ifdef DEBUG_MEM
        debug_mem_output( "strdup, %x, %x, %s, %d\n", 
                        o, s, file, line );
@@ -326,6 +326,20 @@ case_ignore_strcmp(const char *s1, const char *s2)
 
 }
 
+int 
+case_ignore_strncmp(const char *s1, const char *s2, int n)
+{
+       int rv = 0;
+
+       while (n && ((rv = toupper(*s1) - toupper(*s2)) == 0)
+               && *s1) {
+               s1++;
+               s2++;
+               n--;
+       }
+       return rv;
+}
+
 void
 printposn(const double c, int is_lat)
 {
@@ -483,8 +497,6 @@ get_tz_offset(void)
 time_t
 current_time(void)
 {
-       static char *frozen;
-       
        if (getenv("GPSBABEL_FREEZE_TIME")) {
                return 0;
        }
@@ -621,7 +633,7 @@ double degrees2ddmm(double deg_val) {
  * Doesn't try to make an optimally sized dest buffer.
  */
 char *
-strsub(char *s, char *search, char *replace)
+strsub(const char *s, const char *search, const char *replace)
 {
        char *p;
        int len = strlen(s);
@@ -649,6 +661,23 @@ strsub(char *s, char *search, char *replace)
        return d;
 }
 
+/*
+ *  As strsub, but do it globally.
+ */
+char *
+gstrsub(const char *s, const char *search, const char *replace)
+{
+       char *o = xstrdup(s);
+
+       while (strstr(o, search)) {
+               char *oo = o;
+               o = strsub(o, search, replace);
+               xfree(oo);
+       }
+
+       return o;
+}
+
 char *
 rot13( const char *s )
 {
@@ -783,6 +812,32 @@ char * str_utf8_to_cp1252( const char * str )
        return result;
 }
 
+#if 0
+/*
+ * Convert to ISO 8859-1 (LATIN-1). The result is never longer than 
+ * the source.  
+ */
+char * 
+str_utf8_to_8859_1( const char * str )
+{
+       char *result = xstrdup( str );
+       char *cur = result;
+       unsigned char c;
+
+       while (c = *str++) {
+               if (c < 0x80) {
+                       *cur++ = c;
+                       continue;
+               } 
+               if ((c & 0xFE) == 0xC2) {
+                       *cur++ = ((c & 0x03) << 6) | (*str++ & 0x3f);
+               }
+       }
+
+       return result;
+}
+#endif
+
 char * str_utf8_to_ascii( const char * str )
 {
        char *result;
@@ -840,7 +895,7 @@ char * str_utf8_to_ascii( const char * str )
                                cur += bytes - 1;
                        } else {
                                *cur = (char)value;
-                               strcpy( cur+1, cur+bytes );
+                               memmove(cur+1, cur+bytes, bytes+1);
                        }
                }
                cur++;
@@ -860,7 +915,6 @@ strip_nastyhtml(const char * in)
 {
        char *returnstr, *sp;
        char *lcstr, *lcp;
-       int i;
        
        sp = returnstr = xstrdup(in);
        lcp = lcstr = xstrdup(in);
@@ -918,7 +972,7 @@ strip_html(const utf_string *in)
        short int taglen;
        
        if (!in->is_html)
-               return in->utfstring;
+               return xstrdup(in->utfstring);
        /*
         * We only shorten, so just dupe the input buf for space.
         */
diff --git a/uuid.c b/uuid.c
new file mode 100644 (file)
index 0000000..97b6314
--- /dev/null
+++ b/uuid.c
@@ -0,0 +1,37 @@
+/*
+    Copyright (C) 2004 Justin Broughton, justinbr@earthlink.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "uuid.h"
+#include <stdlib.h>
+
+void
+uuid_generate(uuid_t uu)
+{
+       char *cp;
+       int i;
+       for (cp = uu, i = 0; i < 16; i++) {
+               if (getenv("GPSBABEL_FREEZE_TIME")) {
+                       static unsigned char blech = 0;
+                       *cp++ = blech++;
+               } else {
+                       *cp++ ^= (rand() >> 7) & 0xFF;
+               }
+       }
+}
+
diff --git a/uuid.h b/uuid.h
new file mode 100644 (file)
index 0000000..fb8dc02
--- /dev/null
+++ b/uuid.h
@@ -0,0 +1,22 @@
+/*
+    Copyright (C) 2004 Justin Broughton, justinbr@earthlink.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+typedef unsigned char uuid_t[16];
+
+void uuid_generate(uuid_t uu);
diff --git a/vcf.c b/vcf.c
new file mode 100644 (file)
index 0000000..aa6911a
--- /dev/null
+++ b/vcf.c
@@ -0,0 +1,140 @@
+/*
+    Output only format for Vcard format, VCF
+
+    Copyright (C) 2005 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+*/
+
+
+#include "defs.h"
+#include "jeeps/gpsmath.h"
+#include <ctype.h>
+
+static FILE *file_out;
+static void *mkshort_handle;
+
+static char *encrypt = NULL;
+
+#define MYNAME "VCF"
+
+static
+arglist_t vcf_args[] = {
+       { "encrypt", &encrypt,
+               "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL },
+       {0, 0, 0, 0, 0}
+};
+
+static void
+wr_init(const char *fname)
+{
+       file_out = xfopen(fname, "w", MYNAME);
+       mkshort_handle = mkshort_new_handle();
+}
+
+static void
+wr_deinit(void)
+{
+       fclose(file_out);
+       mkshort_del_handle(mkshort_handle);
+}
+
+/*
+ * Print a possibly empty input string, replacing newlines with escaped
+ * newlines as we go.
+ */
+static void
+vcf_print_utf(const utf_string *s)
+{
+       char *p, *p2;
+       char *stripped_html;
+
+       if (!s)
+               return;
+
+       stripped_html = strip_html(s);
+       p = gstrsub(stripped_html, "\n", "\\n");
+       p2 = gstrsub(p, "<p>", "\\n");
+       fputs(p2, file_out);
+       xfree(p);
+       xfree(p2);
+       xfree(stripped_html);
+}
+
+static void
+vcf_print(const char *s)
+{
+       char *p;
+
+       if (!s)
+               return;
+
+       p = gstrsub(s, "\n", "\\n");
+       fputs(p, file_out);
+       xfree(p);
+}
+
+static void
+vcf_disp(const waypoint *wpt)
+{
+       int latint, lonint;
+       
+       lonint = abs((int) wpt->longitude);
+       latint = abs((int) wpt->latitude);
+
+       fprintf(file_out, "BEGIN:VCARD\nVERSION:3.0\n");
+       fprintf(file_out, "N:%s;%s;;;\n", wpt->description,wpt->shortname);
+       fprintf(file_out, "ORG:%c%d %06.3f %c%d %06.3f\n", wpt->latitude < 0 ? 'S' : 'N',  abs(latint), 60.0 * (fabs(wpt->latitude) - latint), wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint));
+
+       if (wpt->url) {
+               fprintf(file_out, "URL:%s\n", wpt->url);
+       }
+
+       fprintf(file_out, "NOTE:");
+       vcf_print_utf(&wpt->gc_data.desc_short);
+       fprintf(file_out, "\\n");
+       vcf_print_utf(&wpt->gc_data.desc_long);
+       fprintf(file_out, "\\n\\nHINT:\\n");
+       if (encrypt) {
+               char *s = rot13(wpt->gc_data.hint);
+               vcf_print(s);
+               xfree(s);
+       } else {
+               vcf_print(wpt->gc_data.hint);
+       }
+
+       fprintf(file_out, "\nEND:VCARD\n");
+}
+
+static void
+data_write(void)
+{
+       setshort_length(mkshort_handle, 6);
+       waypt_disp_all(vcf_disp);
+}
+
+
+ff_vecs_t vcf_vecs = {
+       ff_type_file,
+       { ff_cap_write, ff_cap_none, ff_cap_none},
+       NULL,
+       wr_init,
+       NULL,
+       wr_deinit,
+       NULL,
+       data_write,
+       NULL, 
+       vcf_args
+};
diff --git a/vecs.c b/vecs.c
index 8554510915d438d8aa7a3f313b786af679abf729..f524990c92a57f2d30275a7635d7b1fac4486980 100644 (file)
--- a/vecs.c
+++ b/vecs.c
@@ -1,7 +1,7 @@
 /*
     Describe vectors containing file operations.
  
-    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+    Copyright (C) 2002, 2004, 2005  Robert Lipe, robertlipe@usa.net
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -34,11 +34,13 @@ extern ff_vecs_t geo_vecs;
 extern ff_vecs_t gpx_vecs;
 extern ff_vecs_t mag_svecs;
 extern ff_vecs_t mag_fvecs;
+extern ff_vecs_t magX_fvecs;
 extern ff_vecs_t mapsend_vecs;
 extern ff_vecs_t mps_vecs;
 extern ff_vecs_t gpsutil_vecs;
 extern ff_vecs_t tiger_vecs;
 extern ff_vecs_t pcx_vecs;
+extern ff_vecs_t lowranceusr_vecs;
 extern ff_vecs_t cetus_vecs;
 extern ff_vecs_t gpspilot_vecs;
 extern ff_vecs_t copilot_vecs;
@@ -55,6 +57,7 @@ extern ff_vecs_t quovadis_vecs;
 extern ff_vecs_t gpilots_vecs;
 extern ff_vecs_t saroute_vecs;
 extern ff_vecs_t navicache_vecs;
+extern ff_vecs_t coastexp_vecs;
 extern ff_vecs_t psit_vecs;             /* MRCB */
 extern ff_vecs_t shape_vecs;
 extern ff_vecs_t geoniche_vecs;
@@ -68,6 +71,17 @@ extern ff_vecs_t netstumbler_vecs;
 extern ff_vecs_t HsaEndeavourNavigator_vecs;
 extern ff_vecs_t igc_vecs;
 extern ff_vecs_t brauniger_iq_vecs;
+extern ff_vecs_t hiketech_vecs;
+extern ff_vecs_t glogbook_vecs;
+extern ff_vecs_t vcf_vecs;
+extern ff_vecs_t overlay_vecs;
+extern ff_vecs_t kml_vecs;
+extern ff_vecs_t google_vecs;
+extern ff_vecs_t maggeo_vecs;
+extern ff_vecs_t an1_vecs;
+extern ff_vecs_t tomtom_vecs;
+extern ff_vecs_t tef_xml_vecs;
+extern ff_vecs_t ppdb_vecs;
 
 static
 vecs_t vec_list[] = {
@@ -99,9 +113,15 @@ vecs_t vec_list[] = {
        {
                &mag_fvecs,
                "magellan",
-               "Magellan SD files (as for Meridians)", 
+               "Magellan SD files (as for Meridian)", 
                NULL
        },
+       {
+               &magX_fvecs,
+               "magellanx",
+               "Magellan SD files (as for eXplorist)", 
+               "upt"
+       },
        {
                &mapsend_vecs,
                "mapsend",
@@ -132,6 +152,12 @@ vecs_t vec_list[] = {
                "MS PocketStreets 2002 Pushpin",
                "psp"
        },
+       {
+               &lowranceusr_vecs,
+               "lowranceusr",
+               "Lowrance USR",
+               NULL
+       },
        {
                &cetus_vecs,
                "cetus",
@@ -183,7 +209,7 @@ vecs_t vec_list[] = {
        {
                &gcdb_vecs,
                "gcdb",
-               "Geocaching Database", 
+               "GeocachingDB for Palm/OS", 
                NULL
        },
        {
@@ -213,8 +239,8 @@ vecs_t vec_list[] = {
        {
                &saroute_vecs,
                "saroute",
-               "Delorme Street Atlas Route",
-               ".anr"
+               "DeLorme Street Atlas Route",
+               "anr"
        },
        {
                &navicache_vecs,
@@ -222,6 +248,12 @@ vecs_t vec_list[] = {
                "Navicache.com XML",
                NULL
        },
+       {
+               &coastexp_vecs,
+               "coastexp",
+               "CoastalExplorer XML",
+               NULL
+       },
        {       /* MRCB */
                &psit_vecs,
                "psitrex",
@@ -243,7 +275,7 @@ vecs_t vec_list[] = {
        {
                &gpl_vecs,
                "gpl",
-               "Delorme GPL",
+               "DeLorme GPL",
                NULL
        },
        {
@@ -300,6 +332,72 @@ vecs_t vec_list[] = {
                 "Brauniger IQ Series Barograph Download",
                 NULL
         },
+        {
+                &hiketech_vecs,
+                "hiketech",
+                "HikeTech",
+                "gps"
+        },
+        {
+                &glogbook_vecs,
+                "glogbook",
+                "Garmin Logbook XML",
+                NULL
+        },
+        {
+                &kml_vecs,
+                "kml",
+                "Keyhole Markup Language",
+                NULL
+       },
+       {
+                &vcf_vecs,
+                "vcard",
+                "Vcard Output (for iPod)",
+                "vcf",
+        },
+       {
+               &overlay_vecs,
+               "overlay",
+               "GeoGrid-Viewer",
+               "ovl"
+       },
+       {
+               &google_vecs,
+               "google",
+               "Google Maps XML",
+               "xml"
+       },
+       {
+               &maggeo_vecs,
+               "maggeo",
+               "Magellan Explorist Geocaching",
+               "gs"
+       },
+       {
+               &an1_vecs,
+               "an1",
+               "DeLorme .an1 (drawing) file",
+               "an1"
+       },
+       {
+               &tomtom_vecs,
+               "tomtom",
+               "TomTom POI file",
+               "ov2"
+       },
+       {
+               &tef_xml_vecs,
+               "tef",
+               "Map&Guide 'TourExchangeFormat' XML",
+               "xml"
+       },
+       {
+               &ppdb_vecs,
+               "pathaway",
+               "PathAway Palm Database",
+               "pdb"
+       },
        {
                NULL,
                NULL,
@@ -490,45 +588,72 @@ alpha (const void *a, const void *b)
        const vecs_t *const *ap = a;
        const vecs_t *const *bp = b;
        
-       return strcmp((*ap)->name , (*bp)->name);
+       return strcasecmp((*ap)->desc , (*bp)->desc);
 }
 
-void
-disp_vecs(void)
+/*
+ * Smoosh the vecs list and style lists together and sort them
+ * alphabetically.  Returns an allocated copy of a style_vecs_array
+ * that's populated and sorted.
+ */
+vecs_t **
+sort_and_unify_vecs(int *ctp)
 {
-       vecs_t *vec;
-       style_vecs_t *svec;
-       arglist_t *ap;
        int vc;
        vecs_t **svp;
+       vecs_t *vec;
+       style_vecs_t *svec;
        int i = 0;
 
-#define VEC_FMT "      %-20.20s  %-.50s\n"
-
        /* Get a count from both the vec (normal) and the svec (csv) lists */
 
        extern size_t nstyles;
        vc = sizeof vec_list / sizeof vec_list[0] -1 + nstyles;
 
-       svp = xcalloc(vc, sizeof(style_vecs_t *));
 
+       svp = xcalloc(vc, sizeof(style_vecs_t *));
        /* Normal vecs are easy; populate the first part of the array. */
        for (vec = vec_list; vec->vec; vec++, i++) {
-                       svp[i] = vec;
+               svp[i] = vec;
        }
+
        /* Walk the style list, parse the entries, dummy up a "normal" vec */
        for (svec = style_list; svec->name; svec++, i++)  {
                xcsv_read_internal_style(svec->style_buf);
                svp[i] = xcalloc(1, sizeof **svp);
                svp[i]->name = svec->name;
-               svp[i]->vec = svp[0]->vec; /* Interits xcsv opts */
+               svp[i]->vec = xmalloc(sizeof(*svp[i]->vec));
+               *svp[i]->vec = *vec_list[0].vec; /* Interits xcsv opts */
+               /* Reset file type to inherit ff_type from xcsv for everything
+                * except the xcsv format itself, which we leave as "internal"
+                */
+               if (strcmp(svec->name, "xcsv"))
+                       svp[i]->vec->type = xcsv_file.type;
+               
                svp[i]->desc = xcsv_file.description;
        }
-
        /* Now that we have everything in an array, alphabetize them */
        qsort(svp, vc, sizeof(*svp), alpha);
 
+       *ctp = i;
+       return svp;
+}
+
+
+void
+disp_vecs(void)
+{
+       vecs_t **svp;
+       arglist_t *ap;
+       int vc;
+       int i = 0;
+
+       svp = sort_and_unify_vecs(&vc);
+#define VEC_FMT "      %-20.20s  %-.50s\n"
        for (i=0;i<vc;i++) {
+               if ( svp[i]->vec->type == ff_type_internal )  {
+                       continue;
+               }
                printf(VEC_FMT, svp[i]->name, svp[i]->desc);
                for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) {
                        if ( !(ap->argtype & ARGTYPE_HIDDEN)) 
@@ -537,7 +662,7 @@ disp_vecs(void)
                                (ap->argtype & ARGTYPE_REQUIRED)?"(required)":"");
                }
        }
-               
+       xfree (svp);    
        return;
 }
 
@@ -558,6 +683,18 @@ disp_v1(ff_type t)
        }
        printf("%s\t", tstring);
 }
+
+static void
+disp_v2(ff_vecs_t *v)
+{
+       int i;
+       for (i = 0; i < 3; i++) {
+               putchar(v->cap[i] & ff_cap_read  ? 'r' : '-');
+               putchar(v->cap[i] & ff_cap_write  ? 'w' : '-');
+       }
+       putchar('\t');
+}
+
 /*
  *  Display the available formats in a format that's easy to machine
  *  parse.   Typically invoked by programs like graphical wrappers to
@@ -566,30 +703,38 @@ disp_v1(ff_type t)
 void
 disp_formats(int version)
 {
+       vecs_t **svp;
        vecs_t *vec;
        style_vecs_t *svec;
+       int i, vc = 0;
 
        switch(version) {
        case 0:
        case 1:
-               for (vec = vec_list; vec->vec; vec++) {
-                       if (version > 0)
+       case 2:
+               svp = sort_and_unify_vecs(&vc);
+               for (i=0;i<vc;i++,vec++) {
+                       vec = svp[i];
+
+                       /* Version 1 displays type at front of all types.
+                        * Version 0 skips internal types.
+                        */
+                       if (version > 0) {
                                disp_v1(vec->vec->type);
-                       if (vec->vec->type == ff_type_internal)
-                               continue;
+                       } else {
+                               if (vec->vec->type == ff_type_internal)
+                                       continue;
+                       }
+                       if (version >= 2) {
+                               disp_v2(vec->vec);
+                       }
                        printf("%s\t%s\t%s\n", vec->name, 
                                vec->extension? vec->extension : "", 
                                vec->desc);
                }
-               for (svec = style_list; svec->name; svec++) {
-                       xcsv_read_internal_style(svec->style_buf);
-                       if (version > 0)
-                               disp_v1(xcsv_file.type);
-                       printf("%s\t%s\t%s\n", svec->name, xcsv_file.extension ? 
-                               xcsv_file.extension : "", xcsv_file.description);
-               }
                break;
        default:
                ;
        }
+       xfree (svp);    
 }
diff --git a/waypt.c b/waypt.c
index fde54f87b344e3100183434402205c79278cdc5c..14bbad644f9ac812b0223b6405af16b0d1e88885 100644 (file)
--- a/waypt.c
+++ b/waypt.c
@@ -50,7 +50,7 @@ waypt_dupe(const waypoint *wpt)
                tmp->url = xstrdup(wpt->url);
        if (wpt->url_link_text)
                tmp->url_link_text = xstrdup(wpt->url_link_text);
-       if (wpt->icon_descr && wpt->icon_descr_is_dynamic)
+       if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic)
                tmp->icon_descr = xstrdup(wpt->icon_descr);
        if (wpt->gc_data.desc_short.utfstring) {
                tmp->gc_data.desc_short.utfstring = 
@@ -66,6 +66,10 @@ waypt_dupe(const waypoint *wpt)
         */
        tmp->Q.next = tmp->Q.prev = NULL;
        tmp->gpx_extras = NULL;
+       if ( wpt->an1_extras ) {
+               wpt->an1_extras->copy((void **)(&tmp->an1_extras), 
+                        (void *)wpt->an1_extras );
+       }
 
        return tmp;
 }
@@ -135,6 +139,12 @@ waypt_count(void)
        return waypt_ct;
 }
 
+void
+set_waypt_count(unsigned int nc)
+{
+       waypt_ct = nc;
+}
+
 void
 waypt_disp(const waypoint *wpt)
 {
@@ -252,7 +262,7 @@ waypt_free( waypoint *wpt )
        if (wpt->url_link_text) {
                xfree(wpt->url_link_text);
        }
-       if (wpt->icon_descr && wpt->icon_descr_is_dynamic) {
+       if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) {
                xfree((char *)(void *)wpt->icon_descr);
        }
        if (wpt->gpx_extras) {
@@ -264,6 +274,13 @@ waypt_free( waypoint *wpt )
        if (wpt->gc_data.desc_long.utfstring) {
                xfree(wpt->gc_data.desc_long.utfstring);
        }
+       if (wpt->gc_data.placer) {
+               xfree(wpt->gc_data.placer);
+       }
+       if ( wpt->an1_extras ) {
+               (*(wpt->an1_extras->destroy))((void *)wpt->an1_extras );
+               xfree( wpt->an1_extras );
+       }
        xfree(wpt);     
 }
 
diff --git a/win32/GPSBabelGUI.exe b/win32/GPSBabelGUI.exe
new file mode 100644 (file)
index 0000000..03773b1
Binary files /dev/null and b/win32/GPSBabelGUI.exe differ
diff --git a/win32/README b/win32/README
deleted file mode 100644 (file)
index 132c2c7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-
-This is a Windows front-end for GPSBabel.  It was contributed and is
-maintained by Josh McKee.   It is written in Delphi.
-
-
diff --git a/win32/gpsbabelfront.dpr b/win32/gpsbabelfront.dpr
deleted file mode 100644 (file)
index 777008f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-program gpsbabelfront;
-
-uses
-  Forms,
-  gpsbabelfront_mainform in 'gpsbabelfront_mainform.pas' {FormGPSBabelFront};
-
-{$R *.res}
-
-begin
-  Application.Initialize;
-  Application.Title := 'GPSBabel Front End';
-  Application.CreateForm(TFormGPSBabelFront, FormGPSBabelFront);
-  Application.Run;
-end.
diff --git a/win32/gpsbabelfront.exe b/win32/gpsbabelfront.exe
deleted file mode 100644 (file)
index b719d19..0000000
Binary files a/win32/gpsbabelfront.exe and /dev/null differ
diff --git a/win32/gpsbabelfront_mainform.dfm b/win32/gpsbabelfront_mainform.dfm
deleted file mode 100644 (file)
index 7721ba5..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-object FormGPSBabelFront: TFormGPSBabelFront
-  Left = 208
-  Top = 103
-  BorderStyle = bsDialog
-  Caption = 'GPSBabel GUI Frontend'
-  ClientHeight = 312
-  ClientWidth = 369
-  Color = clBtnFace
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'MS Sans Serif'
-  Font.Style = []
-  OldCreateOrder = False
-  Position = poScreenCenter
-  OnCreate = FormCreate
-  DesignSize = (
-    369
-    312)
-  PixelsPerInch = 96
-  TextHeight = 13
-  object Label1: TLabel
-    Left = 8
-    Top = 292
-    Width = 250
-    Height = 13
-    Anchors = [akLeft, akBottom]
-    Caption = 'GPSBabel: http://sourceforge.net/projects/gpsbabel'
-  end
-  object Label2: TLabel
-    Left = 8
-    Top = 16
-    Width = 43
-    Height = 13
-    Caption = 'Input file:'
-  end
-  object Label3: TLabel
-    Left = 8
-    Top = 80
-    Width = 51
-    Height = 13
-    Caption = 'Output file:'
-  end
-  object Bevel1: TBevel
-    Left = -3
-    Top = 285
-    Width = 380
-    Height = 2
-    Anchors = [akLeft, akBottom]
-  end
-  object Label4: TLabel
-    Left = 16
-    Top = 104
-    Width = 35
-    Height = 13
-    Caption = 'Format:'
-  end
-  object Label5: TLabel
-    Left = 16
-    Top = 40
-    Width = 35
-    Height = 13
-    Caption = 'Format:'
-  end
-  object Label6: TLabel
-    Left = 8
-    Top = 168
-    Width = 33
-    Height = 13
-    Caption = 'Result:'
-  end
-  object comboInput: TComboBox
-    Left = 64
-    Top = 40
-    Width = 297
-    Height = 21
-    Style = csDropDownList
-    ItemHeight = 13
-    TabOrder = 2
-  end
-  object editInput: TEdit
-    Left = 64
-    Top = 16
-    Width = 273
-    Height = 21
-    TabOrder = 0
-  end
-  object editOutput: TEdit
-    Left = 64
-    Top = 80
-    Width = 273
-    Height = 21
-    TabOrder = 3
-  end
-  object comboOutput: TComboBox
-    Left = 64
-    Top = 104
-    Width = 297
-    Height = 21
-    Style = csDropDownList
-    ItemHeight = 13
-    TabOrder = 5
-  end
-  object btnProcess: TButton
-    Left = 288
-    Top = 136
-    Width = 75
-    Height = 25
-    Caption = 'Process'
-    TabOrder = 7
-    OnClick = btnProcessClick
-  end
-  object cbIgnoreShort: TCheckBox
-    Left = 64
-    Top = 136
-    Width = 169
-    Height = 17
-    Caption = 'Ignore "short" names'
-    TabOrder = 6
-  end
-  object btnInput: TButton
-    Left = 341
-    Top = 16
-    Width = 19
-    Height = 21
-    Caption = '...'
-    TabOrder = 1
-    OnClick = btnInputClick
-  end
-  object btnOutput: TButton
-    Left = 341
-    Top = 80
-    Width = 19
-    Height = 21
-    Caption = '...'
-    TabOrder = 4
-    OnClick = btnOutputClick
-  end
-  object memoStdErr: TMemo
-    Left = 64
-    Top = 168
-    Width = 297
-    Height = 113
-    Color = clBtnHighlight
-    ReadOnly = True
-    TabOrder = 8
-  end
-  object OpenDialogInput: TOpenDialog
-    Left = 248
-    Top = 192
-  end
-  object SaveDialogOutput: TSaveDialog
-    Left = 248
-    Top = 240
-  end
-end
diff --git a/win32/gpsbabelfront_mainform.pas b/win32/gpsbabelfront_mainform.pas
deleted file mode 100644 (file)
index 4507e12..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-{
-
-    Copyright (C) 2002 Josh M. McKee, mrsnazz@users.sourceforge.net
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
-
-}
-
-{
-    1.0.0   JMc   First release
-    1.0.1   JMc   - Switched to using AddFormat for populating the formats table
-                  - Updated formats table to include currently supported formats
-                  - Switched to using CreateProcess rather than WinExec, so that
-                    we can display data from stderr to the user.
-    1.0.2   JMc   - Added LoadFormats to call the new -^ switch, to dynamically
-                    load the supported formats from gpsbabel.exe.
-}
-
-unit gpsbabelfront_mainform;
-
-interface
-
-uses
-  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, ExtCtrls, StdCtrls;
-
-type
-  TFormat = record
-    sType:string; // type to be passed to GPSBabel
-    sExt:string;  // default file extension
-    sDesc:string; // description of format
-  end;
-
-  TFormGPSBabelFront = class(TForm)
-    Label1: TLabel;
-    Label2: TLabel;
-    Label3: TLabel;
-    comboInput: TComboBox;
-    editInput: TEdit;
-    editOutput: TEdit;
-    comboOutput: TComboBox;
-    btnProcess: TButton;
-    cbIgnoreShort: TCheckBox;
-    Bevel1: TBevel;
-    btnInput: TButton;
-    btnOutput: TButton;
-    OpenDialogInput: TOpenDialog;
-    SaveDialogOutput: TSaveDialog;
-    Label4: TLabel;
-    Label5: TLabel;
-    memoStdErr: TMemo;
-    Label6: TLabel;
-    procedure FormCreate(Sender: TObject);
-    procedure btnInputClick(Sender: TObject);
-    procedure btnOutputClick(Sender: TObject);
-    procedure btnProcessClick(Sender: TObject);
-  public
-    formats:array of TFormat;
-    nFormatCount:integer;
-
-    procedure LoadFormats;
-    procedure AddFormat(sType,sExt,sDesc:string);
-
-    procedure PopulateCombos;
-    procedure PopulateDialogs;
-  end;
-
-var
-  FormGPSBabelFront: TFormGPSBabelFront;
-
-implementation
-
-{$R *.dfm}
-
-procedure TFormGPSBabelFront.AddFormat(sType,sExt,sDesc:string);
-begin
-  SetLength(formats,nFormatCount+1);
-
-  formats[nFormatCount].sType := sType;
-  formats[nFormatCount].sExt := sExt;
-  formats[nFormatCount].sDesc := sDesc;
-
-  inc(nFormatCount);
-end;
-
-procedure TFormGPSBabelFront.PopulateCombos;
-var
-  i:integer;
-begin
-  for i:=0 to nFormatCount-1 do begin
-    comboInput.items.add(formats[i].sDesc);
-    comboOutput.items.add(formats[i].sDesc);
-  end;
-end;
-
-procedure TFormGPSBabelFront.PopulateDialogs;
-var
-  i:integer;
-begin
-  OpenDialogInput.Filter := '';
-  SaveDialogOutput.Filter := '';
-  for i:=0 to nFormatCount-1 do begin
-    if (formats[i].sExt<>'') then begin
-      OpenDialogInput.Filter := OpenDialogInput.Filter + formats[i].sDesc + ' (*.' +
-        formats[i].sExt + ')|*.' + uppercase(formats[i].sExt) + '|';
-
-      SaveDialogOutput.Filter := SaveDialogOutput.Filter + formats[i].sDesc + ' (*.' +
-        formats[i].sExt + ')|*.' + uppercase(formats[i].sExt) + '|';
-    end;
-  end;
-
-  OpenDialogInput.Filter := OpenDialogInput.Filter + 'All files (*.*)|*.*';
-  SaveDialogOutput.Filter := SaveDialogOutput.Filter + 'All files (*.*)|*.*';
-end;
-
-procedure TFormGPSBabelFront.FormCreate(Sender: TObject);
-begin
-  nFormatCount := 0;
-
-  // load formats from GPSBabel.exe
-  LoadFormats;
-
-  if nFormatCount = 0 then begin
-    ShowMessage('Unable to load format list from GPSBabel.exe. Default format list is being used instead.');
-
-    // add the default formats
-    AddFormat('geo','loc','Geocaching.com .loc');
-    AddFormat('gpsman','','GPSman');
-    AddFormat('gpx','gpx','GPX XML');
-    AddFormat('magellan','','Magellan protocol');
-    AddFormat('mapsend','','Magellan Mapsend');
-    AddFormat('pcx','pcx','Garmin PCX5');
-    AddFormat('mapsource','','Garmin Mapsource');
-    AddFormat('gpsutil','','gpsutil');
-    AddFormat('tiger','','U.S. Census Bureau Tiger Mapping Service');
-    AddFormat('csv','csv','Comma seperated values');
-    AddFormat('xmap','','Delorme Topo USA4/XMap Conduit');
-    AddFormat('dna','dna','Navitrak DNA marker format');
-    AddFormat('psp','psp','MS PocketStreets 2002 Pushpin');
-    AddFormat('cetus','','Cetus for Palm/OS');
-    AddFormat('gpspilot','','GPSPilot Tracker for Palm/OS');
-    AddFormat('magnav','','Magellan NAV Companion for PalmOS');
-    AddFormat('garmin','','Garmin serial protocol');
-    AddFormat('mxf','mxf','MapTech Exchange Format');
-    AddFormat('holux','wpo','Holux (gm-100) .wpo Format');
-    AddFormat('ozi','ozi','OziExplorer Waypoint');
-    AddFormat('tpg','tpg','National Geographic Topo .tpg');
-    AddFormat('tmpro','tmpro','TopoMapPro Places File');
-  end;
-
-  // Set up the dropdown lists and open/save dialog filters using the formats
-  PopulateCombos;
-  PopulateDialogs;
-end;
-
-procedure TFormGPSBabelFront.btnInputClick(Sender: TObject);
-var
-  sExt:string;
-  i:integer;
-begin
-  if opendialoginput.Execute then begin
-    editInput.Text := opendialoginput.filename;
-    sExt := uppercase(ExtractFileExt(editInput.text));
-    for i := 0 to nFormatCount-1 do begin
-      if '.' + uppercase(formats[i].sExt) = sExt then comboInput.ItemIndex := i;
-    end;
-  end;
-end;
-
-procedure TFormGPSBabelFront.btnOutputClick(Sender: TObject);
-var
-  sExt:string;
-  i:integer;
-begin
-  if savedialogoutput.Execute then begin
-    editOutput.Text := savedialogoutput.filename;
-    sExt := uppercase(ExtractFileExt(editOutput.text));
-    for i := 0 to nFormatCount-1 do begin
-      if '.' + uppercase(formats[i].sExt) = sExt then comboOutput.ItemIndex := i;
-    end;
-  end;
-end;
-
-procedure TFormGPSBabelFront.LoadFormats;
-var
-  sIgnoreShort:string;
-  sCmd:string;
-  f:file;
-  Buffer:array[0..255] of char;
-  hRead,hWrite:THandle;
-  StartupInfo:TStartupInfo;
-  ProcessInfo:TProcessInformation;
-  saAttr:TSecurityAttributes;
-  OutSt:TMemoryStream;
-  dwRead:DWord;
-  dwExitCode:cardinal;
-  overlapped:TOverlapped;
-  slstFormats:TStringList;
-  i:integer;
-
-  procedure ExtractFormat(sFormat:string);
-  var
-    toks:array[0..2] of string;
-    i,nTok,nLen:integer;
-  begin
-    i := 1;
-    nTok := 0;
-    toks[0] := '';
-    toks[1] := '';
-    toks[2] := '';
-    nLen := length(sFormat);
-    while ((i<=nLen) and (nTok<3)) do begin
-      if sFormat[i]=#9 then begin
-        inc(nTok);
-      end else begin
-        toks[nTok] := toks[nTok] + sFormat[i];
-      end;
-      inc(i);
-    end;
-    {showmessage(toks[0]);
-    showmessage(toks[1]);
-    showmessage(toks[2]);}
-    
-    AddFormat(toks[0],toks[1],toks[2]);
-  end;
-
-begin
-  slstFormats := TStringList.Create;
-
-  sCmd := 'GPSBabel -^';
-
-  memoStdErr.lines.clear;
-
-  saAttr.nLength := sizeof(TSECURITYATTRIBUTES);
-  saAttr.bInheritHandle := true;
-  saAttr.lpSecurityDescriptor := nil;
-
-  if not CreatePipe(hRead, hWrite,@saAttr,0) then begin
-    ShowMessage('Unable to create pipe!');
-    Exit;
-  end;
-
-  AllocConsole;
-
-  FillChar(StartupInfo,Sizeof(StartupInfo),#0);
-  StartupInfo.cb := Sizeof(StartupInfo);
-  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
-  StartupInfo.wShowWindow := SW_HIDE and SW_SHOWMINNOACTIVE;
-  StartupInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
-  StartupInfo.hStdOutput:= hWrite;
-  StartupInfo.hStdError := hWrite;
-
-  if not CreateProcess(nil,pchar(sCmd),nil,nil,true,CREATE_NEW_CONSOLE,nil,nil,StartupInfo,ProcessInfo) then begin
-    ShowMessage('Unable to execute GPSBabel.exe.')
-  end else begin
-    while (WaitforSingleObject(ProcessInfo.hProcess,0)) <> WAIT_OBJECT_0 do;
-
-    PeekNamedPipe(hRead,nil,0,nil,@dwRead,nil);
-
-    if dwRead>0 then begin
-      OutSt := TMemoryStream.Create;
-
-      repeat
-        if ReadFile(hRead, Buffer, 80, dwRead, nil) then begin
-          OutSt.WriteBuffer(Buffer, dwRead)
-      end;
-      until dwRead<>80;
-
-      OutSt.Seek(0,0);
-      slstFormats.LoadFromStream(OutSt);
-      for i:=0 to slstFormats.count-1 do begin
-        ExtractFormat(slstFormats[i]);
-      end;
-      OutSt.Free;
-    end else memoStdErr.lines.add('Command executed successfully.');
-  end;
-
-  CloseHandle(hRead); CloseHandle(hWrite);
-  FreeConsole;
-end;
-
-procedure TFormGPSBabelFront.btnProcessClick(Sender: TObject);
-var
-  sIgnoreShort:string;
-  sCmd:string;
-  f:file;
-  Buffer:array[0..255] of char;
-  hRead,hWrite:THandle;
-  StartupInfo:TStartupInfo;
-  ProcessInfo:TProcessInformation;
-  saAttr:TSecurityAttributes;
-  OutSt:TMemoryStream;
-  dwRead:DWord;
-  dwExitCode:cardinal;
-  overlapped:TOverlapped;
-begin
-  if (comboInput.ItemIndex)<0 then begin
-    ShowMessage('You must select the input file format.');
-    exit;
-  end;
-
-  if (comboOutput.ItemIndex)<0 then begin
-    ShowMessage('You must select the output file format.');
-    exit;
-  end;
-
-  if cbIgnoreShort.checked then sIgnoreShort := '-s' else sIgnoreShort := '';
-
-  // The output file must exist, or else ExtractShortPathName will not function
-  if not fileexists(editoutput.text) then begin
-    system.assign(f,editoutput.text);
-    system.rewrite(f);
-    system.close(f);
-  end;
-
-  // Construct the command line to execute gpsbabel.exe. ExtractShortPathName
-  // is used to reduce any "long" file/directory names in the paths down to
-  // 8.3 dos format names (this removes spaces, etc).
-  sCmd := 'GPSBabel '+sIgnoreShort+' -i '+formats[comboInput.itemindex].sType+' -f '+
-    ExtractShortPathName(editInput.text)+' -o '+formats[comboOutput.itemindex].sType+' -F '+
-    ExtractShortPathName(editOutput.text);
-
-  memoStdErr.lines.clear;
-
-  saAttr.nLength := sizeof(TSECURITYATTRIBUTES);
-  saAttr.bInheritHandle := true;
-  saAttr.lpSecurityDescriptor := nil;
-
-  if not CreatePipe(hRead, hWrite,@saAttr,0) then begin
-    ShowMessage('Unable to create pipe!');
-    Exit;
-  end;
-
-  AllocConsole;
-
-  FillChar(StartupInfo,Sizeof(StartupInfo),#0);
-  StartupInfo.cb := Sizeof(StartupInfo);
-  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
-  StartupInfo.wShowWindow := SW_HIDE and SW_SHOWMINNOACTIVE;
-  StartupInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
-  StartupInfo.hStdOutput:= hWrite;
-  StartupInfo.hStdError := hWrite;
-
-  if not CreateProcess(nil,pchar(sCmd),nil,nil,true,CREATE_NEW_CONSOLE,nil,nil,StartupInfo,ProcessInfo) then begin
-    ShowMessage('Unable to execute GPSBabel.exe.')
-  end else begin
-    while (WaitforSingleObject(ProcessInfo.hProcess,0)) <> WAIT_OBJECT_0 do;
-
-    PeekNamedPipe(hRead,nil,0,nil,@dwRead,nil);
-
-    if dwRead>0 then begin
-      OutSt := TMemoryStream.Create;
-
-      repeat
-        if ReadFile(hRead, Buffer, 80, dwRead, nil) then begin
-          OutSt.WriteBuffer(Buffer, dwRead)
-      end;
-      until dwRead<>80;
-
-      OutSt.Seek(0,0);
-      memoStdErr.lines.LoadFromStream(OutSt);
-      OutSt.Free;
-    end else memoStdErr.lines.add('Command executed successfully.');
-  end;
-
-  CloseHandle(hRead); CloseHandle(hWrite);
-  FreeConsole;
-end;
-
-end.
-
-
diff --git a/win32/gui/AboutDialogU.ddp b/win32/gui/AboutDialogU.ddp
new file mode 100644 (file)
index 0000000..4370276
Binary files /dev/null and b/win32/gui/AboutDialogU.ddp differ
diff --git a/win32/gui/AboutDialogU.dfm b/win32/gui/AboutDialogU.dfm
new file mode 100644 (file)
index 0000000..8c0b177
--- /dev/null
@@ -0,0 +1,1151 @@
+object AboutBox: TAboutBox\r
+  Left = 713\r
+  Top = 118\r
+  BorderIcons = []\r
+  BorderStyle = bsNone\r
+  BorderWidth = 3\r
+  ClientHeight = 215\r
+  ClientWidth = 316\r
+  Color = clBtnFace\r
+  Font.Charset = DEFAULT_CHARSET\r
+  Font.Color = clWindowText\r
+  Font.Height = -11\r
+  Font.Name = 'MS Sans Serif'\r
+  Font.Style = []\r
+  OldCreateOrder = True\r
+  Position = poScreenCenter\r
+  Visible = True\r
+  OnCreate = FormCreate\r
+  OnShow = FormShow\r
+  PixelsPerInch = 96\r
+  TextHeight = 13\r
+  object pnlOuter: TPanel\r
+    Left = 0\r
+    Top = 0\r
+    Width = 316\r
+    Height = 216\r
+    BevelInner = bvLowered\r
+    BevelWidth = 4\r
+    Caption = 'pnlOuter'\r
+    TabOrder = 1\r
+  end\r
+  object pnlInner: TPanel\r
+    Left = 27\r
+    Top = 27\r
+    Width = 262\r
+    Height = 162\r
+    BevelInner = bvRaised\r
+    BevelOuter = bvLowered\r
+    BevelWidth = 2\r
+    ParentColor = True\r
+    TabOrder = 0\r
+    object lblVersion: TLabel\r
+      Left = 121\r
+      Top = 80\r
+      Width = 136\r
+      Height = 13\r
+      Alignment = taCenter\r
+      AutoSize = False\r
+      Caption = 'Version '\r
+      IsControl = True\r
+    end\r
+    object lblCopyright: TLabel\r
+      Left = 5\r
+      Top = 124\r
+      Width = 252\r
+      Height = 13\r
+      Alignment = taCenter\r
+      AutoSize = False\r
+      Caption = 'Copyright'\r
+      IsControl = True\r
+    end\r
+    object lblLicense: TLabel\r
+      Left = 5\r
+      Top = 137\r
+      Width = 252\r
+      Height = 13\r
+      Alignment = taCenter\r
+      AutoSize = False\r
+      Caption = 'License'\r
+      Layout = tlCenter\r
+    end\r
+    object lblProductName: TLabel\r
+      Left = 121\r
+      Top = 38\r
+      Width = 136\r
+      Height = 19\r
+      Alignment = taCenter\r
+      AutoSize = False\r
+      Caption = 'GPSBabelGUI'\r
+      Font.Charset = ANSI_CHARSET\r
+      Font.Color = clWindowText\r
+      Font.Height = -15\r
+      Font.Name = 'Times New Roman'\r
+      Font.Style = [fsBold, fsItalic]\r
+      ParentFont = False\r
+    end\r
+    object ProgramIcon: TImage\r
+      Left = 11\r
+      Top = 10\r
+      Width = 110\r
+      Height = 110\r
+      Picture.Data = {\r
+        07544269746D6170C6820000424DC6820000000000003604000028000000B400\r
+        0000B40000000100080000000000907E0000232E0000232E0000000100000000\r
+        0000B3D6E000ADD5DE00A7D4E000ADCEDE00A5CEDE009FCCE000ADCCD500A6CD\r
+        D500A4C8DC009DC6DB00A5C6D60099CCCC00A5C5CE009CC4D6009DC3CE009AC0\r
+        D4009BC5C600A9C3C40094C5C6009CBECE0094BDCE00A3BFC50094C5BD008FC2\r
+        C2009CBDC500A7BEBD0093BDC4009CBDBE0095BDBD009AB8C4008DBEBD0094B6\r
+        C6009DBAB6008CB5C50095BAB6009BB5BC0094B5BD008DB5BE00A3B6B5009CB5\r
+        B50093B5B50079AEC9008BB5B50093B0BB009CB4AF0084ACC60084B4B50083AE\r
+        BC0094AEB50094B2AD008CACBD008CB2AE008CADB50099AEAD0085ACB50094AD\r
+        AD0084ADAD008CACAD007BADAD0092ACA60079A4BC008DACA60083A6B50085AA\r
+        A7008AA6AC0092A7A4007BA3B40084A4AE007CA5AD008CA5A50084A5A60073A5\r
+        A5007BA3A6008DA39C0085A49D00799DAD008A9F9D00829EA3007B9CA500849D\r
+        9C008B9E96007B9D9B007499A5006D9D9C00859B94007E9C95007B979C008398\r
+        94006699990073959D00739596007B9494006B939000738E920070928C00738C\r
+        8C006B8C8D00628C8D005A8B8C006C8985006B848400628483005A8382005384\r
+        84005B7C7C00517B7B004A7B7A0051757300427373004A7271003D707000436B\r
+        69003B6A6B00336666003A63630029585A002558580029555300215052001C4F\r
+        4F001F4C4B00104A4A001949480011424100083A3A0000333300000000000000\r
+        000000ECFD0020002200C22DF80070F1FC007294F8005894F800080200001A02\r
+        000018A51A00080000000E0000000C0000000000000001350000100000000200\r
+        00003477120008771200000000002E4502000100000064AAFF00000000004300\r
+        00009E7512002000000040000000030000000000000020000800000000002000\r
+        220000ECFD000000000043000000A07512000000000000000000200000000000\r
+        0000A803130010A51A0000E0FD0000E0FD00E0771200A79DFB007894F800FFFF\r
+        FF00F07712001A02000008000000F0771200C22DF80070F1FC005696F8002E96\r
+        F80000ECFD000000000001800000000000000000000000000000000000000200\r
+        000063003A005C00740065006D0070005C0073006800690070002E0067006900\r
+        66000000000000000000000000007774E80090020000E8751200F07512000800\r
+        00000E000000407D120020D6FF000A0000000000000000000000000000000000\r
+        0000000000000000000000000000000000000001000000000000407D12009720\r
+        650090020000000000000000000001000000A544620090020000000000000100\r
+        00001E456200407D1200000000000100000006734200407D1200407D120020D6\r
+        FF00000100000A000000D0CF1100A1B11A000067610054C1CE008553000000A1\r
+        F9000000000000000000C029F80000010000D80A600017000000A87800006C76\r
+        12000B0B0B1010102A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A3F3F3F3F462A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A2A2A2A2A2A2A2A2A1E1E1E1E1212120B0B0B0B0B0B0B10101038383838\r
+        3838383838333338383838383838383838383833333838383838383838383838\r
+        3838333338383838383838383838383833333838383838383838333338383838\r
+        3838383838383838383833333838383838383838383838383333383838383838\r
+        3838383838383833333838383838383838383838383333383838383838383833\r
+        3338383838383838383838383833333838383838383838383838383333332A2A\r
+        2A1E1E1E1212120B0B0B0B0B0B10101C3F3F3F2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A\r
+        2A2A2A2A2A2A2A2A2A2A2A2A2A3F3F3F3F3F33332A2A1C1C1212120B0B0B0B0B\r
+        0B1212123F3F3F38383838383333383838383838383838383838333338383838\r
+        3838383838383833383838383838383838383838333338383838383838383838\r
+        3838333338383838383838383838383838383333383838383838383838383838\r
+        3333383838383838383838383838383333383838383838383838383838333338\r
+        3838383838383833333838383838383838383838383333383838383838383838\r
+        384646463F3F3F333333221C1C12120B0B0B0B0B0B0B1010101C1E3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F464646463F3F3F3933281C\r
+        1C1212120B0B0B0B0B0B12121C282A3F46464646463F3F3F3F3F3F3F4646463F\r
+        3F3F3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F4646463F3F3F3F3F3F3F\r
+        3F3F46464646463F3F46463F3F3F3F3F3F3F3F3F3F4646464646463F3F3F3F3F\r
+        3F3F4646463F3F3F3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F463F4646\r
+        463F3F3F3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F4646464646463F3F\r
+        3F3F3F3F3F3F3F46464A4A4A4A3D3D3D333328281C1212120B0B0B0B0B101010\r
+        1C282A3838383838333338383838383838383333383838383838383838383838\r
+        3333383338383838383838383333383838383838383838383333383338383333\r
+        3838383838333338383838383838333338383838383838383333383838383838\r
+        3838383838383333383838383838383838383838333338383838383838383838\r
+        38383333383838383838383838383838383333383838383838383838384A4A3D\r
+        3D31313122221C1C1C12120B0B0B0B0B0B1010101C222A2A38613F3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F1B1B393F3F3F3F3F3F3F3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F\r
+        38383838383F3F3F3F3F3F3F3F3F3F3F3F39313120202019191919101010100B\r
+        0B0B0B0B0B10101C31313D3D3D31313D3D3F31313D3D3D31313D3D3F3F3F3F3F\r
+        3F3F3F3F46464646463F3F3F3F3F3F3F3F3F4646463F3F3F3F3F3F3F3F3F4646\r
+        463F3F33383838383338383846463F3F3F4646464646463F3F3F3F3F3F3F4646\r
+        463F3F3F3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F463F4646463F3F3F\r
+        3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F3F3F3F3F3F4A3F3F3F3F3F3F\r
+        3F27272727272C2C2C2C2C2C201B1B1B101010100B0B0B0B0B12121211192020\r
+        20202020202C1119202020202020201920352C1919192031313D3D3D31313D3D\r
+        191B1B1B38383338383838333838381B1B1B1B0C0C1B1B1B1B1B1B1B1B1B1B1B\r
+        0C0C0C0C00003838383833333838383838383838333338383838383838383838\r
+        3838333338383838383838383838383833333838383838383838383838383333\r
+        38383838383838383F3F3F3F3F3931313D3D31315E3B2C2C2C3B494945454545\r
+        313128281C1212120B0B0B0B0B0B121219191920352C19192C3F19191920352C\r
+        19192C31313D3D3D31313D3D1920202006000600000C0C0C1B1B1B1B1B1B1B1B\r
+        1B1B1B0C0C0C0C03060C0C0C0C0C0C0C0C0C0C0C06060606061506000600003F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F\r
+        3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F38383838\r
+        3831202020202020654F4F4F4F55555555554F464639392A1C1C1C120B0B0B0B\r
+        0B1010101C281E100C1920202020202020202020202019111920202020202020\r
+        1919060006000006150603060C0C0C0C0C0C0C0C0C0C0C060606060303030306\r
+        030303030000110611060600060011061106153F3F3F3F3F3F3F3F3F46464646\r
+        463F3F3F3F3F3F3F3F3F4646464646463F3F3F3F3F3F3F3F3F46464646463F3F\r
+        3F3F3F3F3F3F3F46464631313D3D31312020202020202C19192C3B415555555B\r
+        5B5B5B5B5B51514D4D3F392A2A1C1C120B0B0B0B0B1010101C22100C07191920\r
+        352C19191920352C19191919191920352C19192C2C1911061106150003030003\r
+        0606060606060606060606030306060303030303030006110600060000201106\r
+        1106153131313D3D3D31313D3D3131313F3F31313D3D3D31313D3D3131313F3F\r
+        3131313D3D3D31313D3D3131313F3F31313D3D3D31313D3D3131313F3F312020\r
+        202020202C19192C3B4155555563685B5B5B5B5B5B5B5B5B5B51514D4646392A\r
+        2A1C12120B0B0B0B0B10101C1C2210101019191920352C19191920352C191919\r
+        1920352C19191920352C19191906000600000003030303030303030303030303\r
+        030303060006030300060C191106110615191920203131201119202020202020\r
+        2020202031312019202020202020202020203131201119202020202020202020\r
+        2031312019202020202020202020203131202C19192C3B415B5B5B5B5B5B5B5B\r
+        5B5D5D5D5D5B5B5B5B5B5B5B5B5B51514646382A2A1E17120B0B0B0B0B121212\r
+        1C222828283D45455B656550505049495054545454545050505045352C2C4149\r
+        491106110615060603030003060603030303000603030011060C0600002C452C\r
+        19191920352C191941413B3B19191920352C19192C3B4141413B3B191920352C\r
+        19192C3B4141413B3B19191920352C19192C3B4141413B3B191920352C19192C\r
+        3B4141413B3B4F5B5B5B5D5D5D5D5D5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B\r
+        5B5B51514646382A2A1E12120B0B0B0B0B0B12121C2833333D454A4A4F4F4F50\r
+        5050505050505454545450505050494141414950505050504920110C06000006\r
+        150C06000600000C0600002C2C2C455B4D4D4D4D4D4D4D4D4E4E4E4E4E4E5959\r
+        4F3B3B4A55554F4F5A60606064646464645F5F5F4F3737454F4F454F5B5B4519\r
+        19223F4F3B222222394F4F493B3B494F412C3B4F5B5B5B5B5B5B5F5F5F5B5B5B\r
+        5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B51514646382A2A1C1C12\r
+        0B0B0B0B0B1010101C28333D3D45494950505050505050505050545454545450\r
+        50505050505050505050505049412C2C455B201135201106110615412C2C455B\r
+        5B5B5B5B5B5B5B5B5B5B5B5B5B5D5D5D5D5D5D5D5D5D5D5F6364646464646565\r
+        65656464645F5F5F5F55555D5D5D5A5A5A56463B3B4D565656564D4D565D5D5D\r
+        5B5B5B5B4F4F5B5D5D5D5D5F5F5F5D5D5D5B5B5D5D5D5D5D5D5D5D5D5D5D5D5D\r
+        5B5B5B5B5B5B5B5B5B5B5B51514638332A1E17120B0B0B0B0B1010101C223333\r
+        3D454C4C50505050505054545450505050505050505054545454545454545450\r
+        505054505050412C49412C2C2C2C455B5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F63\r
+        636364646464646464646465656565656564646464646464635F5F5F5F5F5F5F\r
+        5F5A5A5A5A565656565A5D5D5D5D5D5D5D5D5D5F5F5F5F5D5D5D5D5D5D5D5D5D\r
+        5D5D5D5D5D5D5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5D5D5D5D5D5D5D5B5B5B51\r
+        514638332A1E17120B0B0B0B0B10101C1C2233333D45454C4C4C545454545454\r
+        5454545454545454545454545454545454545454545450505054545454545454\r
+        50505B5B5D5D5D5D5D5D5F5F5F5F5F5F5F5F5F5F636464646464646464656565\r
+        6565646464646464646464635F5F5F5F5F5D5B5B5B5B5B5B5A5A5A5D5D5D5D5D\r
+        5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5F5F5F5F5F5D\r
+        5D5D5D5D5B5B5B5B5B5B565656564D4D4D4D46393934342A1C1C12120B0B0B0B\r
+        0B1212121C2233333D3D49495454545454545454545454545454545454545454\r
+        5454545454505050505050505054545457575757575B5D5F5F5F5F5F5F5F5F5F\r
+        5F5F5F5F5F5F5F5F63646464656565646464646464646464646464646464645F\r
+        5F5D5D5D5D5B5B5B5B5B5B5B5D5D5D5D5D5D5D5D5B5B5B5B5B5B5D5D5D5D5D5D\r
+        5D5D5D5D5D5D5D5D5D5D5D5B51515D5D5D5D5D5B55555B554A3D454530302318\r
+        181818181818180C0C0C1C1C1010100B0B0B0B0B0B1212121C22333345454A4A\r
+        5454545454545454545454545454545454545454545454545454545454545454\r
+        54545457575757575B5B5D5F5F5F5F5F5F5F5F5F5F6363636363636363646464\r
+        646464646464646464646464646464646464635F5F5D5D5D5D5D5D5F5F5F5D5D\r
+        5D5D5D5A5A5A5A5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D564D\r
+        4D4D554F4F4F4F454A4A4A452820201D0E15150C0C0C0C0C0C0C0C0C0C102222\r
+        1C1212120B0B0B0B0B1010101C1C33333D454A4A545454545454545454545454\r
+        54545454545454545454545454545B575757505050505757575757575D5D5D5F\r
+        5F5F5F5F5F5F5F5F636363646464646464646464646464646464646464646464\r
+        64646464645F5F5F5F5F5D5D5D5D5F5F5F5F5A5A5A5D5D5D5D5D5F5F5F5F5F5F\r
+        5F5B5B5B5B5F5F5D5D5D5B5B5B5B55554C4039394545454545454545454A4A37\r
+        23282824181119202015151520201515151C22221C1C12120B0B0B0B0B0B1212\r
+        1C1C33333D3D4A4F4F4F57575757575754545454545454545454545454545454\r
+        545B5B57575454545454545454545B5B5F6363635F5F5F636363636363646464\r
+        6464646464646464646464646464646464646464646464645F5F5F5F5F5F5D5D\r
+        5D5F5F5F5D5D5D5D5F5F5F5F5F5F5F5F5F5F5F5D5B5B5B5B5B5B5B554F4F4F4C\r
+        4C393939303030373B414141454545454545452824343E342719273937202020\r
+        20201B1B1B2222221C1C12120B0B0B0B0B0B12121C1C28333939454A4A4F5757\r
+        57575757575757575757575757575454545454545B5B5B4F5757575757575B5B\r
+        5B5B5F5F5F5F5F5F636363646464646464646464646464646464646464646464\r
+        646464646464646464645F5F5F5D5D5D5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F\r
+        5F5F5F5F5B5B5B5555564E4E4E4E45453B3B3B3B352727272731313D3D454545\r
+        454545453740391B1B2F3E34271928453B262626261B1B1B2222221C1C101010\r
+        0B0B0B0B0B1010101C1C2833333945454C4C4F54545454545454545457575757\r
+        57575754545454545B5B574F54545454545B5B5B5B5F5F59525252595D636464\r
+        64646464646464646565656565656464646464646464646464646464635F5F5F\r
+        5F5F5F5F5F5F5F5F5F5F5F5F5F5D5D5D5D5D5D5B5B5B5B5B4F4F454A4A3E3E3E\r
+        3E343535353541372727272727373D3D3D3D3D3D3D454537372828281D2F2F2B\r
+        1B1B2737372626261B1B1B282828281C1C1010100B0B0B0B0B1010101C1C2828\r
+        37373D45454C4C4C4C4C4C4F4F4F4F4F4F57575757575757575757575B5B5454\r
+        545454545B5B5B5952525242424242525A646464646464646464646464646464\r
+        6464646464646464646464636363636363636363635F5F5F5F5F5F5F5F5F5F5F\r
+        5D5A5B5B5B5B5B4F4F4F4F4F45454545402F3E3E3E24273B3B3B3B2727272727\r
+        3737454545453B3B3B3B3030301A1A34342F2F2323232327262626261B1B3028\r
+        2828281C1C1010100B0B0B0B0B0B12121C1C282839394545454549494949494C\r
+        4C4C4C4C4C4F4F57575757575757575B5B5B5457575757575B594B3C3C3C3C4B\r
+        5D5D52595D646464646464646464646464646464646464646464646464646464\r
+        64646464646363635F5F5F5F60606060605D5D5D5B515151464545454A4A4A4A\r
+        4F4F4F45342F2F3E3418233B3B3728283527273745454545453B3B3B3B3B2828\r
+        341F1F3232322B2020202026262C2C2C2C3131313128281C1C1010100B0B0B0B\r
+        0B0B12121C1C282837373D45454549494949494949494949494F4F4F57575757\r
+        5757575B5B575757575B4E4B4B4B3C3C42424B5A63635F5F5F5F636363646464\r
+        646464646464646464646464645F6364646464646464635F5F5F5F5F5F5F5F60\r
+        60605D5D564F4F4F45454545454545454A4A4A4F4F4F4F392F2F2F3E30151B37\r
+        302327272727313B3B3B3B3B3B373737373728283424181F2D2D282020202626\r
+        2C2C2C2C373737373728281C1C1C10100B0B0B0B0B0B10101C1C282837374141\r
+        4141494945454545494949494949494F4F4F57575757575B5B4F4F575B4E3C29\r
+        293C3C4B52595D5F63636363635F5F5F5F5F6363636464646464646464646464\r
+        645D5D6464646464605F5F5F5F636363635F5F5B5B554C453B3B4A4A4A45454F\r
+        4F4A4A4A4A4F4F4F4F4F45342F2F3E4334181828232323232330373737373737\r
+        373737373730301A1A1A1A212D322326262626262C2C2C2C282828282828281C\r
+        1C12120B0B0B0B0B0B0B10101C1C222231313B3B414141414141414545454545\r
+        454545454C4F4F4F4F4F4F5B5B57574E3C29293C3C3C3C525A5F636363646464\r
+        6363636363635F5F5F5F5F636364646464646464645D5D646464646464646060\r
+        5D5D5A564D4D4D4545453B373D4A4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F3D34\r
+        2D2F3E3E3931241D1D27272727373737373737373737373730302B1A0E0E1F2D\r
+        2F2B1B262626262C272727282828282828281B1B1B12120B0B0B0B0B0B0B1010\r
+        1C1C222231313B414141414141414141414145454545454C4C4C4C4C4C4F5B5B\r
+        5B5B563C3C3C4B595952595D5F636363636363636363636363636363635F5F5F\r
+        5F636363636363635F5F5F646464635F5F5F55392434343425303B3737373737\r
+        454F4F4F4F4A4A4A4A45454F4F4F4F4F4F4539322D3E3E4037371C0E1B272727\r
+        273737373737373737372727272424241A0E142D3E2319262626262626262C2C\r
+        2C37373727271B1B1B12120B0B0B0B0B0B0B10101C1C22282837373B41414141\r
+        414141414145454545454C4C4C4C4C4C4C4F5B55555D5D59595D5D5F5F5F5F64\r
+        64646464636363636364646464636364646464636363636360606060605B5B5A\r
+        5A5A514D4D4D3B15030E212121373B3B3B3B3B4545454545454545454545454D\r
+        4D4D4D4D4545393E3E3E43373737241823232323313737373737373737272727\r
+        23243434240E143C321B1B262727272727273137373737272020201C1C10100B\r
+        0B0B0B0B0B0B10101C1C22282837373B3B4141414141414141454545454C4C4C\r
+        4F4F4F4F4F4F5B5B5B5F5F5F6363635F5F5D5B5D606063636363636464646464\r
+        646464636363636363635F5F5F5D5D5D5D5643434B4D45454545350C03081F25\r
+        34393B3B3B3B454545454545454545454545454D4D4D4D454545342F3E3E403B\r
+        3B302B28282828283737373737373737372727231D2534341D0D213C2B191926\r
+        2C2C2020273737373737272020201C1C1010100B0B0B0B0B0B0B10101C1C2228\r
+        31313B3B4145454545454545454545454F4F4F4F4F4F4F45454F5B5F5F5F5F5F\r
+        5F5D5D564D404040464D4D56565B5D5D5D5B5B5B5B5B5B5B5656565B5B5B5B5B\r
+        55554D4D4D4D3E3E3E4645454545310C0303133239393B3B3B45454545454545\r
+        454545454545454D4D4D4D454545362D3E434039342525282828282837374545\r
+        372C373727271B18181A25250A092D3E2323232C2C2626273737373737272727\r
+        27271C1C1010100B0B0B0B0B0B0B1010101C222831313B3B4145454545454545\r
+        4545454A4A4A4A4A4A4545454A5D5D5D5D5B5B5B5B4F45393030303025303737\r
+        37414545453B393939394046464646564D454545454539394646424242464545\r
+        4545350C0303031834393939454545454546464646463D3D454545454D4D4646\r
+        4545362F2F43342B212128282828373737374C4C353535352727180E0E25250E\r
+        04143C341920202020202037373737372626262727221C1C1010100B0B0B0B0B\r
+        0B0B1010101C222831313B3B414545454141414141454A4A45454F4F45454545\r
+        4F5D5D5D5D5D564F453730303037372525303737373B3B3B3B3B454545454545\r
+        4545454E453737454545393946442F3E464545454545370C0303030318304040\r
+        464646464646464645453B45454545464646454545403E2F3636321F1F343737\r
+        28283939373746403030302727230E0D1F34340D08213C2B1927272727272737\r
+        373737272727272722221C1C1010100B0B0B0B0B0B0B1010101C222831313B41\r
+        41414141414141414C4C45454C4C454545453B45565D5D5D5B4D373737373030\r
+        30303025253939454545454545454545454545454545454D453B3B4A4A4A3939\r
+        4D442F3E4D4D49494949370C01040101061830404D4D4D4D4D4D4D453B3B3B45\r
+        4545454545454545393936323232212121343728283737393939434337372727\r
+        271808081F341F070D2D3E272727272727373737372C2626262C2C2323231C1C\r
+        1010100B0B0B0B0B0B0B10101C1C222831313B3B414141414141454545454545\r
+        4A454545454543424B4E403940463B3535353537373739393945454545454539\r
+        39393941414141414141454545454545453939433E3E3E46464F4F45454C370C\r
+        010401010A18243040404D4D4D4D453B3B3B4545454545454545453434323232\r
+        3232212134393024303B3B3939393737373727271B0E0408242B0F030F293E27\r
+        2727272727373737372626262C2C232322221B1B1010100B0B0B0B0B0B0B1010\r
+        1C1C282831313B3B41414141414C4A4A4A45454545454D4D4B422F2F39392B28\r
+        3745454537374545453939363639393930303030373741414141414141414141\r
+        41393945453434362D2D434A454D4D4A4A4A3B15030303080D18182424344046\r
+        46393030394545454545453934342B2B21212525252525253437271A25404039\r
+        37373737372727271808040D32320A08143C3427272727273039393527272727\r
+        27271B1B281B1B1B1B10100B0B0B0B0B0B0B10101C1C222831313B4141414145\r
+        454545454545454D4D4D4D443E323437373737373745454D4545454539302525\r
+        252537373737373741414141414141414141414141373745331C2B2F293C4B46\r
+        39394F4F4F49411B0303080D0D1D242424243636251F1F1F343443393939321F\r
+        1F1F1F1F1F25252525252532343023233436363636393B3B2C2727230E04040F\r
+        211F0A0A2D2F30262626273739393527262626151B1B2323231B1B1B1010100B\r
+        0B0B0B0B0B0B1010101C1C282837373B3B4145454545454545454B4B56564039\r
+        39393D3D3D40404040373745453B3737371D1D21212130303737414141414141\r
+        4141414141414141413737403424323C3C423E34343434464F4C412706060D0D\r
+        14212121212525130D0F141F2532323232321F1F1F1F1F1F1F2B2B2B2B323232\r
+        30302323393934252532404027272718040408131F1F13142D34272727273740\r
+        403527262626261515232323231B1B1B1010100B0B0B0B0B0B0B1010101C1C28\r
+        282837373B454C4C45454646464444445B5B4537414145393939373030303030\r
+        3939353535180E2121213037373B414141414141414141414141414137373734\r
+        34403E29423E212121212134464639280E0A0A0E1A1F1F1F1F1F0A03080D0D1F\r
+        32321F1F25251F1F1F1F2525252525323232323234301D1D4040372824242121\r
+        2B2B2B0C0303080E24342D292D302626263740403526262626262C2323232320\r
+        20201B1B1010100B0B0B0B0B0B0B1010101C1C1C28282839454F4F46464B4242\r
+        4234344A5B4F4539393939302424303030303030303D3D3D3D1D0A142525303B\r
+        3B3B3B414141414141414141414141413739343232432F2D3E32131F32212121\r
+        34433424180A0D1A1A1A1A1A1A0A010103030C1F251D1D1D251F1F1F1F1F1F2B\r
+        2B2B2B343421213434281818343939373727130F213632140D04040D32432F2D\r
+        2F3019233745453526262626262C2723232323232323231B1010100B0B0B0B0B\r
+        0B0B1010101C1C1C1C2828454D4D4D4343433636333337454545373737372828\r
+        1C2430303030303030304545391D0A0D1F252537414141414141454545414141\r
+        414141413936323236362D2D3E1F0E252525252525343425180E1F1F1F1F1F1F\r
+        080101010103131F1313131F1F14141F1F1F2B34342B2B323232323230241D1D\r
+        3437373737371B152436362D140909142F34212D34231B374645352626262626\r
+        2C271B232827202020201B1B1010100B0B0B0B0B0B0B1010101C1C1C28284046\r
+        4843343434343737282828282828282828282828283428282323282828303939\r
+        301D0E040A1F25343B3B3B3B3B3B45454541414141413934343221323E3E2D42\r
+        3E0E08252525252525253434281A25251A21210801010101010E1F0E0A131313\r
+        1313131F1F1F2B2B2B32323232323232342418182439393737272727271D1D21\r
+        140F1F2F342B2F3E2B1B2745452C272727272727271B1B2828272727271B1B1B\r
+        1010100B0B0B0B0B0B0B1010101C1C2834343E3E252428283737373724242427\r
+        272727272727272730343423232323303030242434280E02020A1325343B3B3B\r
+        3B3B3B3B3B3B3B3B393934323232323236362D42340A0A252525252525252546\r
+        46282525251F0902010101010714140A0A131313131313131F1F2B2B2B2B3232\r
+        323232323928180E1830303030272731280708130A0414322B343E3218183745\r
+        3527272727272727271B283527272727271B1B101010100B0B0B0B0B0B0B1010\r
+        101A1A2A2A1A1A2424243030303030301B1B282828282828282828282834342B\r
+        2B30303030242424393918040404040D1D2B3939393939393939303434342532\r
+        32323232362F2F422B030834342525252525344F4F392424240D010101010101\r
+        0F1408040D0D0D08080D0D131F2424242432323232323232392B0E0E0E232837\r
+        2C2727301801040D0D0D0D0D0F3E3E242424373727272727272727271B243030\r
+        27272727271B1B101010100B0B0B0B0B0B0B1010101A1A252512182828282828\r
+        282828281B1D2B28282828282828282839393232322B2B242424242437453007\r
+        02020208080D141F1F2B3232323232323225323232323232362F2F3E18010A34\r
+        342525252525404F4F4F2A1F0D0101020202020D140D040408080803030A0A13\r
+        1F2424242424243232323232391D0E0E0A0A28372C2C37280A03030414322815\r
+        0D2534342424302626272727272727182430302727272727271B1B1B1010100B\r
+        0B0B0B0B0B0B101010101C1C1C1C1C3030282828282727271D1D2B2B27272727\r
+        2730303030343232322B242424243030303B3B18020404040404080D0D141F21\r
+        212121252525323232323232362F3E3E0C000D343425252525344A4A4A4F380E\r
+        01010101010108140D0404090908010104040A1D242424242424243232323232\r
+        2B180F0F03031D283535351803030309142B3B30141F34391D24403427272727\r
+        27271D24343737373737372727271B1B1010100B0B0B0B0B0B0B101010101C1C\r
+        1C1C282828282727272727271B1A303027272727303030303939252525253030\r
+        303037373737372B0A0202020202020808080F141F1F1F252532323232323232\r
+        362F42400C000D323232252534464F4F4F4F460E010101010108140F04040909\r
+        0902020202020A1D1F1F1F1F1F1F25323232323224180D030007070C3045280C\r
+        03030D21232339433E3E464023233E3E3E302727271B1B303027273030303027\r
+        271B1B1B1B10100B0B0B0B0B0B0B101010101C1C1C2828282828272727272727\r
+        1B1B30302727272730302730393925252534393737373737373737371D040404\r
+        0404040404040A0D141F1F32323232323232323232324B400C010A2B2B2B2B2B\r
+        404D4D4D4D4545300A02020202141408020809090401010101040E1D1D131313\r
+        1F1F1F2B2B2B2B342B130400010A03031D39270A0A0F1F1B27404D4D4E4E4E43\r
+        39272734343434342323282827272727272727271B1B1B1B1010100B0B0B0B0B\r
+        0B0B0B1010101C1C1C2424243030303030282828232330272727272727272730\r
+        39393232323037373737373737373737370E040404040404040404080D131F25\r
+        2525323232323232323E4E390C000A3232242B40464D4D4D453B3B4523040101\r
+        0D140D020409090901010101010A18180D0A0E0E1F1F1F25252525342B0A0000\r
+        0404000A131D1D0C0D212B1924424E4E4E4E4E4E43392C26232B343434343027\r
+        272727272727271B1B1B1B1B1010100B0B0B0B0B0B0B0B101010101C1C282828\r
+        2828282828282828282828282727272730303030393932322B2B2B2B30303030\r
+        3737373737240E040404020202040404040A131F1F1F25252525253236444D37\r
+        0C00082525253646464F4F4545453745450E02090F0F04040404090401010101\r
+        0813130A03080A13131F1F1F2B2B2B361F0100020202020C0C0C0E0E14242727\r
+        2B2F424E4E4E4E4E4E4E433027272324344343372727272727271B1B1B1B1B1B\r
+        1010100B0B0B0B0B0B0B0B101010101C1C242823232828282828282828283434\r
+        2727272727272730393934252528282828282828282837373728180D04020202\r
+        0202020202020A131F1F25323232323236434D370C01081F3434434D4D4D4545\r
+        4545453034340E0E0E080408080808020101010413130A0101080A13131F1F1F\r
+        1F2525362403000404010A0A0A0A13141F1F273737303E4B4334343440404039\r
+        30271B24303034344037272727271B1B1B1B1B1B1010100B0B0B0B0B0B0B0B10\r
+        1010101C1C1C2823232828272727273728283434282727272731313139393425\r
+        2B2B2B2B2B2B2B2B3737373737371B1309020202020404040404040A13131F25\r
+        32323232324345370C010A1F3939464D4D454545454530242440401A09040808\r
+        080802010101010A130D010101030A0E0E1F1F1F1F1F25362B07010303070E08\r
+        08080D131F1F1F303030434B3E1B1B2737373737271D1D282828282834404040\r
+        2727271B1B1B1B101010100B0B0B0B0B0B0B0B101010101C1C1C28281D243027\r
+        27273030272734343430302C2C37373737392B2B303030303030303037373737\r
+        373D37180E08020202040404040404040A0A141F32323232324040370E020D25\r
+        464D4D4D4545454545371D1D25404F390E040909090401010101041313020202\r
+        0203030A13131F1F1F1F1F32320E0000040D0D010808080E0E0E141F24344B4E\r
+        341B2727373737271D1D283737272727273039393939271B1B1B1B101010100B\r
+        0B0B0B0B0B0B0B101010101C1C1C28281D2430272727303027272B3434343430\r
+        303939373739342530303030303030303737373737374527130D040102020504\r
+        02020202020A131F1F322525253445370E040E344D4D4D4545454545451B151F\r
+        34404A4A30130D0D0801010101010F1408010101010101080E0E1F1F1F1F1F1F\r
+        341300000D0D030308080808080F0F14141F32362B2323373737271D1D283737\r
+        3727272727272727392B2B2B231B1B101010100B0B0B0B0B0B0B0B101010101C\r
+        1C1C28281B1B3428282828372823283432323234343434373739343428283030\r
+        3030303030303737373745341B130A01010404040202020404040A131F252525\r
+        253434300E08254D564D393941454545300C15243945454545391D0A04040101\r
+        010D140D02010101010101030A131F1F1F1F1F1F321801041308000404040401\r
+        010A0E141414141F1F1F24303030231D273737272727272727272723231D1D28\r
+        281C1C101010100B0B0B0B0B0B0B0B101010101C2424243023182B3030272737\r
+        3727273434253232323230303939342B2B313030303131313131313939392B2B\r
+        2B27130401010404040404040404040A1321212525323428181A46564D34343D\r
+        3D3D45451506153446453737454A4018040404010A1F0E020202020201010101\r
+        0A131F1F1F1F1F1F251F0A0A0A0101080808020000030A0F141F1F1F1F1F1F25\r
+        34241D2B3737372B2B2B2B2B2B2B2B242424242424241B1B1010100B0B0B0B0B\r
+        0B0B0B1010101C1C1C1C1C302318213434282828373728343434343434343431\r
+        3139343030303037373737373737373737231F25393B28180701010505020202\r
+        020202080E1F25323232343434434D4D3424343D3D3D3D2806031540463D3D3D\r
+        3D4646371B0E08081318030101010101010101010A141F1F1F1F1F1F1F251D0A\r
+        0301040404040101010103080F141F1F1F1F1F1F25252B2B3232323232322121\r
+        21212121242427271B1B1B1B1010100B0B0B0B0B0B0B0B1010101C1C1C282828\r
+        2818143634342B2B373727303934342B2B2B2B35354034343030303737373737\r
+        3737373723182134373737372408020404040404040404040A141F2525253434\r
+        464D341A2525343B3B453B1503031839393939393939454537231818180D0401\r
+        01010103030303030D131F1F1F1F1F1F1F2B1F07010108080802010101010108\r
+        0E141F1F1F1F1F1F2B342B21212121212121212121212B2B27272727271B1B1B\r
+        1010100B0B0B0B0B0B0B0B1010101C1C1C28282828150E343434343434303030\r
+        3934323232323030303934343131373737373737373737371518213437373737\r
+        391804040404040404040404080E1F1F2525323446390A0A252539414145370C\r
+        030A1834393939393939394545372B2B1D0E0D04040403030303030A0F0F141F\r
+        1F1F1F1F1F251F0701080404040101010101010813131F1F1F1F1F1F34341F1F\r
+        1F1F1F1F1F1F1F1F2430302727272727271B1B1B1010100B0B0B0B0B0B0B0B10\r
+        10101C1C1C282828281B0C253432323232322B2B3434342B2B2B2B3535393930\r
+        30303030373737373737371B0C1F25303030303737371B070404040404040404\r
+        0808131F25252534340E01082434394141452706031313153745393939393939\r
+        45372424241313130A0D0D0D0D0D0D131414141F1F1F1F1F1F321F0A03080404\r
+        04010404040404080A13131F1F1F1F343424242424242424241F1F3230302727\r
+        27272727271B1B1B1010100B0B0B0B0B0B0B0B1010101C1C1C28282837230A1F\r
+        3632323232322B2B30343425252530303039393030303030303030303737270C\r
+        0C1F253030373737374545280C04040404040404080808131F1F1F322B0A0008\r
+        1F343741414115030E180A062345393939373737402B2B2B37241D1313131313\r
+        131314141414141F1F1F1F1F1F252513080808080404040403030303080D131F\r
+        1F1F34342B2B2B2B2B2B1F1F1F1F32303027272727272727271B1B1B1010100B\r
+        0B0B0B0B0B0B0B1010101C1C1C28282837280C0D323232323232282837392B2B\r
+        2B343030303939303030313131313137373715030A1F32393737373737374545\r
+        30130A08040404080808080D141F1F25251803031434394149370C0C1F0A0101\r
+        18394539373737372B2525373737372514141313131313131414141F1F1F1F1F\r
+        1F1F321F0A0A0D080404040101010303030A13131F1F1F1F1F252525251F1F1F\r
+        1F32302727272727272727271B1B1B1B1010100B0B0B0B0B0B0B0B1010101C1C\r
+        1C28282837370C04253434323232303030393425253437373739393030303131\r
+        3131313131270C030A18343937373737373737454537231308080808080D0D0D\r
+        131F1F1F25240C031334394141270C1313010108081B4545373737281A243939\r
+        394545403221141414141414141414141F1F1F1F1F1F2525130D080401010101\r
+        01010101010813131F1F131F1F1F25252525252525302727272727272323231B\r
+        1B1B1B1B1010100B0B0B0B0B0B0B101010101C1C1C1C2828283718011A343434\r
+        343430303039342B2B34373737373939283030303030303037150303030C3039\r
+        3737373737373737454545301D0E0E0E0E0E131313131F1F1F321D0A13403D3D\r
+        3D23180F03000404040A23404545301D1D244545454545464B43251A14141414\r
+        14141414141F1F1F1F1F1F321F080202010101010101010101030D1F1F1F1F1F\r
+        1F242424242424322B272727272723232323231B1B1B1B101010100B0B0B0B0B\r
+        0B0B101010101C1C1C282828283723030E343434343430303039393434343737\r
+        373739392828282828282837270C010303032439393037373737373739464545\r
+        402514131313131313131F1F1F3232180E34454545280E0400030A040404061D\r
+        3D30242418283D4545454544444E4D34251F1F14141F1F1F1414141F1F1F1F25\r
+        250C0104040101010101010101030D1F251F1F1F1F2424242424322B2B202323\r
+        232323232323231B1B1B1B101010100B0B0B0B0B0B0B101010101C1C1C1C2828\r
+        2837300A0325342B2B2B2B313131393434343737373739393030303030303037\r
+        2306010101010E303B3737373737373737404641402F2F2B1F1313141414141F\r
+        1F2525250E1F404545240701010A04040A0A010618181839393937374D464342\r
+        4B4D4D4D45302414141F1F1F1F1414141F1F1F1F251D03030303030303010101\r
+        010313241F1F1F1F1F1F2B2B2B2B2B2B2727272723232327272727271B1B1B1B\r
+        1010100B0B0B0B0B0B0B0B1010101C1C1C1C28282837370E010E323232323030\r
+        3030393434343737373739393131303030303030150303030303081D37373737\r
+        37373737373D4646433C4E4E341F14141F1F1F1F1F1F25251F1F404A451D0303\r
+        08080308080303030A0E243939393939434E4E4E4E4E4646453737241F1F1F1F\r
+        1F141F1F1F1F1F1F1F2B0C010101010303010101010A181F141F1F1F1F1F2B2B\r
+        2B2B2B27272727272727272727272727271B1B1B1010100B0B0B0B0B0B0B1010\r
+        10101C1C1C242430303030180108253434343437282839343434343131313939\r
+        31313030303037270C0101010103030D2B393737373737373737464E4E4B5656\r
+        5640241F1F1F1F1F1F1F1F252525404F390C03030A030308030303080A0A1824\r
+        3037343E4E4E4E4E4E434343393930303030241F14141F1F1F1F1F1F1F251D03\r
+        0101010104040401030C1313131F1F1F1F1F1F25252B27272727272727272727\r
+        27272727271B1B1B1010100B0B0B0B0B0B0B101010101C1C1C24243030303030\r
+        03011F3434343431313131393434343131313939372730303030392306010101\r
+        0303030A142B373737373737404D4E4E4E4E4E4E4E463930241F1F1F1F1F1F25\r
+        2525344023060A0E08030A0A0100030A0A0A0A0A1D373E3C4E4E4B4B4B4B4D4D\r
+        4040373737373734241F1F1F1F1F1F1F1F1F2B1803000000020202020D0D0D0D\r
+        141F1F1F1F2525252B2B2727272727272C2C2C2727272727271B1B1B1010100B\r
+        0B0B0B0B0B0B10101010101C1C1C2430303030300C000D343434343030303039\r
+        3934303030303040372727303737371503030202020208080814303937373730\r
+        3E52524B4B4E4E4E4E4D454139301F1F1F1F1F1F2525253415030A130A0A0A01\r
+        01010808030A030308182B3E4B4B4B4E4E4E4E4E4E464040373737372B1D1313\r
+        13141F1F1F1F25250E0301010101010A0E0A0A0E1F1F1F1F1F1F1F2530353535\r
+        3535353535353535352C272727271B1B1B10100B0B0B0B0B0B0B0B101010101C\r
+        1C1C1C28282828281801011F3434343030303039393430303030304037272730\r
+        3037370C0303030303030808080A1F34393937302F4B524E4E4E4E4E4E4E4D4D\r
+        454539241F1F1F1F1F2525251D0C06060E0E080000080801080801010408131F\r
+        2F424B4B4343434E4E4646392834404030241D0E0E14141F1F1F1F2B2B0E0303\r
+        0301040A0A03030E1F1F1F1F1F1F25253035373737373737372C2C2C2C2C2C2C\r
+        27271B1B1B10100B0B0B0B0B0B0B0B101010101C1C1C1C28282828282807000D\r
+        34343430272727393939393030303040392C2C303030230A0302020202020202\r
+        02080F1F2B343939303E4B4B4E4E4E4E4E4E4E4E46454545342B2B1F1F1F1F25\r
+        25250C060C0E0A0308080404040101010104040D1F2F3E3E2424404640404034\r
+        34393939303024180E04040F1F1F1F1F32240C030303080A0300030D141F1F1F\r
+        1F32322B272727272737373737272C2C2C2C2C272727221C1C1010100B0B0B0B\r
+        0B0B0B101010101C1C28282828373730300E01041F3634342727273040403430\r
+        303030393935303030301B03030303040404040404040D0D142434393737434B\r
+        4B3E3E3E46464646464541414141302B2B1F1F1F252525180A030A0E0E040108\r
+        040001010103030A1314212124243939393939303039392B2B30183418010104\r
+        040F14141F3232180C0C0A0A0000080E0E1D1D1D25252B272727272727272727\r
+        27272727272727272222221C1C1010100B0B0B0B0B0B0B1010101C1C1C1C2828\r
+        28373728282304010D3434342727273039393430303030393937303030301503\r
+        020202040404040404040A0A13131F323439434E4E32243145454545453B3B3B\r
+        3B3B3B341D14141F25253232180A0A1F1F0A040401010101010104080D131314\r
+        1F3439393940343434393030301D0E34371507070000040A0A14323636251807\r
+        0303030D131F1F1F1F2524232323232323232323232323232727272727271C1C\r
+        1C1010100B0B0B0B0B0B101010101C1C1C1C28282837282828280A01021F3934\r
+        282828283939393030303030393737373737150302020202040404040404040A\r
+        0E0E1F1F1F323E4B4B2B2B394545454545453B3B3B3B45390A03132525252525\r
+        25252D2D2F250E0401010101010103030A0F0F141F1F25343434343434343439\r
+        39180E2440371B0701010303030A1D3443433E321A07070D14141F1F1F2B2B1B\r
+        1B1B1B1B1B232323232323202020202727271B1B1B1010100B0B0B0B0B0B0B10\r
+        10101B1B1B1B28283030303030301803010F3639282823233739392828282828\r
+        3939273030300C030202020202020202020202080A0E0E1F1F25323434343434\r
+        344545393939393939394A3D0C01132418181F1F2525363E3E3E250F04040101\r
+        00000303080D1313131F1F1F2532323234343434341D181D343430180E0E1818\r
+        181F2525251814212F1D0A0A13131F1F1F24241B1B1B1B1B1B1B1B1B1B1B1B1B\r
+        1B1B1B2727271C1C1C1010100B0B0B0B0B0B0B1010101C1C1C1C282828282828\r
+        2828230A010425403030232330393930302727303939282828280A0302020202\r
+        02020202040404040A0A0E0E1F25252525323434343440393939393939454545\r
+        23071818180E0E0E1F1F24343E42422F1F14090404040404040A13131F1F1F1F\r
+        1F1F1F1F2525252525252525252525252525251F1F3232130803030808080A0A\r
+        0F0F1F1F1F1F231B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B272727221C1C10100B\r
+        0B0B0B0B0B0B0B1010101C1C1C1C2424243030302424301302020D3639282828\r
+        28393939282727273939282828230A040404040404020202040404040A0A0A13\r
+        1F1F252525323636363636343434343434343434342B2B2B2B2B1F1F1F323232\r
+        1F13142D2D0D05050909020202080D13131F1F1F1F1F1F1F1F1F1F2525252525\r
+        2525323232212121211F0A030303030300030A0E0E0E1D1D24241B1B1B1B1B1B\r
+        1B1B1B1B1B1B1B1B1B1B1B1B2222221C1C10100B0B0B0B0B0B0B101010101C1C\r
+        1C1C242424303030232337230701021443302727303039392828232339392828\r
+        28280A04040404040404040404040404040A0A131D1D25323232323636363636\r
+        3636363636363636363636363632323232321F0D030303090902020202020203\r
+        03030A0A131F1F1F1F1F1F1F1F25252521212121213232323221211F1F0A0300\r
+        0003030000030A0A1313131F2B232323231B1B1B1B1B1B1B1B1B1B1B1B1B1B1B\r
+        1B1B1C1C1C10100B0B0B0B0B0B0B0B1010101C1C1C1C24242424242424243030\r
+        180202043239282828283939372727273440303030300C040404040404040404\r
+        0404040404080A131F1F1F323234343434363636363636363636363632323232\r
+        323232321F0D04010101010101010101010101010101080A131F1F1F1F1F1F25\r
+        25252525252525253232323232322424180A0A0303030303030A0A0A1313131F\r
+        2B2B2727271B1B232323231B1B1B1B1B1B1B1B1B1B1B1B1B1010100B0B0B0B0B\r
+        0B0B0B101010101C1C1C1C282828282828232330230A01010F40302727303939\r
+        392727273040392730300E0404040404040404040404040404040E0E141D1D25\r
+        2534343436363636363636363636363232323232323232140801010104040404\r
+        04020101010101010101030A0E0E1F1F1F1F1F25252525252525253232323232\r
+        322B2B3430180D0D0A0A0A0A0A0A0A0A13131324303030272323232323231B1B\r
+        1B1B1B1B1B1B1B1B1B1B1B1B1010100B0B0B0B0B0B0B0B101010101C1C1C2424\r
+        2424242424242424301804020421342828282839393030272739392727270A04\r
+        04040404040404040404040404040D0D131F1F1F323232363636363636363636\r
+        3636323232323232321F13040101010404040202020201010101010103030308\r
+        0D13131F1F1F1F1F252525253232323232323232303030394D391D1313131313\r
+        0A0A0A0E0E0E1F2B373737373737272727271B1B1B1B1B1B1B1B1B2727271C1C\r
+        1C1010100B0B0B0B0B0B10101010101C1C1C2424242424242424242430270E04\r
+        04092B3030303039393928282828393030230A04040404040404040404040404\r
+        0408080A131F1F1F32323236363636363636363632323232323232321F130A03\r
+        03030304040402020202020202010101030303080D13131F1F1F1F1F1F253232\r
+        3232323232323239393939454D4D401D13131313131313131313132B373B3B3B\r
+        3B3B3B353535272727272727272727272727221C1C1010100B0B0B0B0B0B0B10\r
+        1010101C1C1C2424242424242424242430301D0802021F393123233039392828\r
+        2828393930230A040404040404040404040404040808080A13131F1F25253436\r
+        3636363636363636363632323232341818180404040404040404040404020202\r
+        02010101010303080A13131F1F1F1F1F1F25253434323232362B1D2440394545\r
+        4D4D4537270E0E13131313131313132B3B3B3B3B3B3B3B3B3B3B3B3535353535\r
+        353535352828221C1C1010100B0B0B0B0B0B0B101010101C1C1C1C2828282828\r
+        232323232B2B2B180402092B37232328374037272727393928230A0204040404\r
+        04040404040404040404040A0E0E1F1F25253232323636363636363636323232\r
+        32393923230E010404040404040402020202020202010101010103080813131F\r
+        1F1F1F1F1F3232343434343434130718404030434E463B3B3B27180D0D131313\r
+        13131F2B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3737373737372828221C1C101010\r
+        0B0B0B0B0B0B0B101010101C1C1C1C2828282828232323232B2B2B230C02020F\r
+        2B2B2727304040282828283928230A040404040404040404040404040404040A\r
+        0A131F1F2525323236363636363636363636363640454530240D020202020202\r
+        080802020202020202010101010103030A0A131F1F1F1F1F2525323434343434\r
+        130404131F342B3446463D3B3B3B3B230E0E13131313132B3B3B3B3B3B3B3B3B\r
+        3B3B3B3B3B3B3B3B3B3B37373728221C1C1010100B0B0B0B0B0B0B1010101C1C\r
+        1C1C1C28282828282823232323303023230A0104213927272330403027273039\r
+        39230C04040404040404040404040404040404080A131F1F1F25323236363636\r
+        363636363636364045454528180D040404040404040404040202020202010101\r
+        010101040A0A0E141F1F1F1F252532323434320F04040A0A0A1F343E40404A45\r
+        45454541311D0D0D1313132B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B37373737\r
+        3722221C1C1C10100B0B0B0B0B0B0B1010101C1C1C1C1C242424243024232323\r
+        2328282323230702092B37232323393928232834393018040404040404040404\r
+        04040404040404080A13131F1F25253436363634343434343434454545453928\r
+        180D040404040404040404040404040401010101010101080A0A0E141F242424\r
+        2432323636210D0202080A0A0A13243230454545454545454C4124181313132B\r
+        414141414141414141413B3B3B3B3B3B373737372828221C1C1C12120B0B0B0B\r
+        0B0B0B101010101C1C1C1C2424242424242323232323302323301803010E3430\r
+        23151D403723233039301B0A040404040404040405050505050505080A0E0E1F\r
+        1F25253434343434343434343445454545393937180D04040404040404040404\r
+        040404020101010101010108080D13131F1F1F25253434341F040202080D0808\r
+        0A0E0E0E24303030394145454545453728231D2B45414141414141414141413B\r
+        3B3B3B3B3B3B37373728281C1C1C10100B0B0B0B0B0B0B101010101C1C1C1C1D\r
+        1D24242424232323232330242424281501021434271B0C1F393023283434230A\r
+        04040404040404040505050404040408080D131F1F2532343434343434343434\r
+        4545454545244545180D08010404040404040202020202020201010101010308\r
+        0A0A13131F1F252534343424080104090F0802020A0A0A131F1F1F2424303039\r
+        393939454537243443464541414141414141413B3B3B3B3B3B3B37373728281C\r
+        1C1010100B0B0B0B0B0B0B101010101B1B1B1D1D1D1D1D1D242424241D1D2B2B\r
+        232323230E02082B37271509243928283434230C040404040404040404040404\r
+        04040808080D131F1F253434343434343434344045454545301C4545230E0A01\r
+        04040404040402020202020202020101010101080A0A13131F1F2B2B3443340C\r
+        0208080F0902020A04040A13131D1D1D24242424242424243234373943434545\r
+        41414141414141413B3B3B3B3B3B37373728281C1C1C10100B0B0B0B0B0B0B10\r
+        1010101C1C1D1D1D1D1D1D1D242424242424242424242424240C020D3430300A\r
+        092530232B39300C04050505040404040404040404040408080E0E1F1F252534\r
+        3434343434344045454545453939454537180D02020404040402020202020202\r
+        02020203030303030A0E0E1F1F2525253643300C0404040404040D0801030A0E\r
+        0E1D1D24242421212121212134343B3B3B3B45454545453B3B3B3B3B3B3B3B3B\r
+        3B3B3B313128281C1C1C10100B0B0B0B0B0B0B101010102424181D1D1D1D1D1D\r
+        24242323232323303023232323230A041434301B051434272439391504050505\r
+        0404040404040404040404040A0E0E1F1F253434343434343440454545454539\r
+        3945454545280E0303030308040404020202010101010101040408080D13131F\r
+        1F1F252532403715020208040408080202030A0A131D1D252525252525252539\r
+        454141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B313128281C1C1C1010\r
+        0B0B0B0B0B0B0B101010101C1C1D1D1D1D1D1D1D24242323232323232B2B2B2B\r
+        2B2B1D0A042430300E091F372334401B03040404040404040404040404080808\r
+        080D131F1F25343434343434394545454545453945454545493B180801010104\r
+        0404010101010101010101010104040A0E141F1F1F3232323439391D01040404\r
+        080802020203080A131D1D253232323232323945454141414141414141413B3B\r
+        3B3B3B3B3B3B3B3B3B3B3B313128281C1C1C10100B0B0B0B0B0B0B1010101018\r
+        181818181D1D1D1D1D2B2323232323232B2B2B23232323230C0A2430230C0D2B\r
+        2B2B40300A040505050404040404040404040408080D131F1F25343434343434\r
+        4545454545454545454545454545341A03030303030303030303010101010103\r
+        0303030A0E141F1F2B2B3434393939240C040404080401020202030A131F1F25\r
+        32323232344045454545454141413B3B3B3B3B3B3B3B3B4141413B3B3B3B3B37\r
+        372828281C1C12120B0B0B0B0B0B0B0B10101018181818181D24242424242424\r
+        242424242B2B2B2B23232323230C1325301D0E18302434391802020505050505\r
+        0504040404040404080A131F1F25252525253439454545454545454545454545\r
+        39344030040303030303040404040101010101040303030A13131F1F2B323640\r
+        3B302B3423040408040101040404030A131F1F1F323232344045454545454141\r
+        413B3B3B3B3B3B3B3B3B3B414141414141414137372828281C1C12120B0B0B0B\r
+        0B0B0B0B0B101018181818182323232323232323232424242430242323232323\r
+        232318182B2B1B1B34282436240A0404040404040404040404040404040A131F\r
+        1F2525252525343D454545454545454545454537252545390A03030303030303\r
+        03030101010104030303080A131F1F252534344537151A3630180D0401010104\r
+        040101030E1D2424243234404545454545414141414141414141414141414141\r
+        414141414141413B313128281C1C12120B0B0B0B0B0B0B0B1010101010101D1D\r
+        1D2424232323232323242424243030232323232323232318243023233439212F\r
+        30180D05040404040404040404040404080D13131F3232323234394545454545\r
+        393945454545271D253945452303030303030303030303030303030303030A0E\r
+        1D1D242434343945230C1A3439391D0401010101010101030E1D1D1D25253945\r
+        4545454545454545414141414141414141414141414141414141413B3131281C\r
+        1C1C12120B0B0B0B0B0B0B0B101010101010101D1D1D24232323232323232323\r
+        2330302323231D1D1D1D24232334301D2439323239270E040404040404040404\r
+        08080808080D13131F252525253945454545453B3B3B454545280A14343D3D3D\r
+        451B0A0A040303030303030303030303030A0A141F1F1F25343445370C0C2439\r
+        45453713030303030303030313131F1F24344545454545454545454545414141\r
+        414141414141414141414141414141373728281C1C1C12120B0B0B0B0B0B0B0B\r
+        0B101010101313131D1D1D1D1D1D242423232323232330231D1D1D1D1D1D2424\r
+        242439231D25363434371B0A040404040808080808080404080D13131F252525\r
+        34394545454545373D3D3D3D370C0C243939454545451B0C0803030303030303\r
+        08080808080E0E1F1F2525253440492302022445454545240E0A0A030303030A\r
+        13131F1F34454545454545454545414141414141414141414141414141414141\r
+        414141373728281C1C1C12120B0B0B0B0B0B0B0B0B0E0E0E0E13131313131D1D\r
+        1D1D1D24241D23232323232323231D1D1D1D2323232332300C1F3E343434270C\r
+        0A0A040404040409080404040A0E0E1F1F252525343D45454545393939454545\r
+        23060C2B40454545454C37180A0707070703030A0A0A0A0A13131F1F1F242424\r
+        39454518010113454C3D3D3D1D13130A0A0A0A0A13131F2B3945454545454545\r
+        4141414141414141414141414141414141414141414141373728281C1C1C1212\r
+        0B0B0B0B0B0B0B0B0B0E0E0E0E13131313181D23232323232323232323232323\r
+        23231D1D1D1D1D1D1D1D1D24151432393030301B0E0E08040404040404080808\r
+        080F0F1F1F32323239454545454537373D3D45300C030A2B4545454539454537\r
+        180A0A0A0A0A0A0A0A0A0A0E0E1F1F1F1F1F25254045450C03030A2445454541\r
+        391F13131313131313131F2B4045454545454545414141414141414141414141\r
+        4141414141414141414137373728281C1C1C12120B0B0B0B0B0B0B0B0B0E0E0E\r
+        0E131313131D232323232323232323232323232B2B23231D1D1D1D1D1D1D1D1D\r
+        1D3221343434303024130A0A0A0A0A04040408080D0D141F2525253440403D3D\r
+        3D3D37373745452303030324454545453945454530180C130E0E0E0E0E0E0E0E\r
+        1F1F1F1F1F25252539493B0A0408080C2B454541464324131313131313131F34\r
+        454545454545454141413B3B3B3B414141414141414141414141414141413737\r
+        3728281C1C1C10100B0B0B0B0B0B0B0B0B101010131313131D1D232323232323\r
+        23232323231D1D24241D1D1D181818181818180A13362B2434342B2B2B230E0A\r
+        0A0A0A0A030303080A131321212B323939454537373737373745370C03030318\r
+        4545454545394C4C4C391D1313131313131313131F1F1F1F1F32322B3745300A\r
+        040908030E304545464D3923130F131313131F394541414141414141413B3B3B\r
+        3B3B3B3B3B3B41414141414141414141413737373728281C1C1C10100B0B0B0B\r
+        0B0B0B0B1010101010181818232323232323232323232323231D1D1D241D1D1D\r
+        1D18181818180C03081F39242434343030301D1D0E0A0A0A0A0808080D131F25\r
+        252525253D45454537373737374028060101030A374C454545394545454D341F\r
+        1F1F1F1F1F1F1F1F1F242424242434394141270A0A0802020218303043464137\r
+        281A1313131324404541414141414141414141413B3B3B3B3B3B414141414141\r
+        41414141413737373728281C1C1C10100B0B0B0B0B0B0B0B101010101010101D\r
+        1D1D23232323232323232323232318181D1D18181818181818180A03030D2434\r
+        2B2B343427272724140F0F0A0A0A0A0A13131F25253224243745454539393939\r
+        39391B03030303031845454545374545454D4D40241F1F1F1F1F1F1F24242424\r
+        242434454545280C04040101010A182B40403B3B45391D131313243D45414141\r
+        414141414141414141414141414141414141414141414141414137373728281C\r
+        1C1C10100B0B0B0B0B0B0B0B1010101010101010101D1D232323232323232323\r
+        2323231818241818131313131D130404040A132B3434343428282828251F1413\r
+        1313131313141F25253234373737453737414141413715030303030303234545\r
+        45453945454D564D2B2B1F1F1F1F1F1F1F1F1F2B2B2B34454545280A01010101\r
+        0108132534343B4545453B2318132441414141414141414141413B3B3B3B3B41\r
+        414141414141414141414141413737373728281C1C1C10100B0B0B0B0B0B0B0B\r
+        101010101010101010101D2323232323232323232323231818241D1813131313\r
+        130C03030808131D2B34283434272730432F1F1F1F1F1F1F1F1F1F2525254045\r
+        373739393941414141370C0000030308080C284545453939464E4E392439341F\r
+        1F1F1F1F24242424242439454539280A03040404040A0E0E14253939393B3B3B\r
+        28131F45414141414141414141413B3B3B3B3B41414141414141414141414141\r
+        413737373728281C1C1C10100B0B0B0B0B0B0B0B0B1010101818181818181823\r
+        231D1D1D1D2323232323231818181D1313131313130A03030808131D1D243434\r
+        342823344E4E321F1F1F1F1F1F1F1F1F32323939373737373B3B3B3B45270600\r
+        010101010A0A15304545373446564637374545341F1F1F1F1F1F1F2525253941\r
+        3730300C08080808080D0D0E1824323234343434342424434541413B3B3B3B3B\r
+        3B3B3B3B3B3B3B414141413B3B3B41414141413B3B3B3B373728281C1C1C1010\r
+        0B0B0B0B0B0B0B0B1010101018181818181818181D1D1D1D1D1D24241D181818\r
+        18181D1D131313181808030303080F1F1F1F253440392343564634251F1F1F1F\r
+        1F1F1F1F323239414130303D3D3D3D3D4527030001010101080808133445452B\r
+        434E3931454545454525251F1F1F1F2525344545373737070404040404040404\r
+        0A1F1F1F25323232323939393B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B4141413B\r
+        3B3B3B4141414141414141373728281C1C1C10100B0B0B0B0B0B0B0B10101010\r
+        181818181D1D1D1D1D1D181818181D1D181818181818181D1313131818040404\r
+        040409141F23232334242448564528282B1F21211F1F1F1F3232394141303045\r
+        45454545452303010101010404040A0F1D30463E3E3E46464C41414141413421\r
+        21212B2B253445453939410C020205040401030308131F21212121343941413B\r
+        3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B41414141414141414137\r
+        3728281C1C1C12120B0B0B0B0B0B0B0B10101010131313131D1D1D1D1D1D1D18\r
+        18181818181818181818181D181818180E0804040404040D142B2B231A1A4352\r
+        4E402727302B211F1F1F1F1F323237414131314545454545452703030404040A\r
+        0A0A0A13132436424246464D4D4D454541414140322121212134454539394923\r
+        0102050202020303030C1D212125343D4141413B3B3B3B3B3B3B3B3B3B3B3B3B\r
+        3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3131281C1C1C10100B0B0B0B\r
+        0B0B0B0B10101010101313131313131818181818181818181818181818181818\r
+        181818180C040404040404080F1F322B232B4B4B43433928282828251F1F1F1F\r
+        323437414137373D4545454545270A040808080D0A0A0A0A131F1F323E45454F\r
+        4F4F4F454545454C4C403232253434283D3D493B0C02020101010101030A1321\r
+        323941414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B\r
+        3B3B3B3B3B3737373728281C1C1C10100B0B0B0B0B0B0B0B0B0E0E0E13131313\r
+        131313131318181818181818180E0E0E0E181818181818180C04040404080808\r
+        08132132304342363446463939393939251F1F25253439393939393945453737\r
+        37230A04040404040404040A0E0E0E1F253439393B4545454545454949494940\r
+        32323224304141492303010101010101040A1324344141414141414141413B3B\r
+        3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3737373728281C\r
+        1C1C10100B0B0B0B0B0B0B0B1010101013131313131313131313130E0E0E0E0E\r
+        0E0E0E0E131313131D1D1D1D0A040404040404040A0D142525363636373D3D3D\r
+        394040404032212121343B3B3B3B393939393939392707010101010101040404\r
+        040A13131F25252530303939454545454545454534343E3E2437414141150101\r
+        0101010103080E24394141414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B\r
+        3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B313122221C1C10100B0B0B0B0B0B0B10\r
+        1010101313131313131313131313130E0E0E0E0E0E0E0E0E0E0E0E181D1D1D1D\r
+        0A040404040404040808131F1F25253434343030303B39394545342121343930\r
+        39393939393939454C300601010101040408040103080E0E1F1F252525253434\r
+        343434343434343434344343433B3B3B493B0C010101010101030E2437413B3B\r
+        3B41414141414141414141414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B\r
+        3B3B3B3B313122221C1C10100B0B0B0B0B0B0B10101010131313131313131313\r
+        1313130E0E0E0E0E13131313131313181824241D0A0404040404040808080D14\r
+        1F1F25323232322B34373737374539343434341D1D394545454545454C300701\r
+        010104090902020202080A131D1D2525253434343434343232323434343D4141\r
+        4643393B3B41350C0202020203030E2B41413B3B3B4141414145414141414141\r
+        4141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B313122221C1C1010\r
+        0B0B0B0B0B0B0B101010101313131313131313131313130E0E0E0E0E0E181818\r
+        18181818182424180A040404040404080808080F141F1F252525253234343434\r
+        3434343434344B3627374545454545454535070102020808040202020202080E\r
+        181F25323232323232323232323945393945454541393939393B3B3414070104\r
+        0404133041414141414141414141414141414141414141413B3B3B3B3B3B3B3B\r
+        3B3B3B3B3B3B3B3B3B3B3B3B313122221C1C10100B0B0B0B0B0B0B0B10101010\r
+        131313131313131313131313130E0E0E0E181818181818181824241B0A040404\r
+        040404040404080D13131F1F2525323232323232323232323737434B433B3B45\r
+        454545454C370A0108080404040404040404040C131D25323232323232323232\r
+        40403B3B414141413945453B3B3B3B3636280C020203183741413B3B3B3B3B41\r
+        41414141414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B\r
+        313122221C1010100B0B0B0B0B0B0B0B10101010131313131313131313131313\r
+        130E0E0E0E0E0E0E181818181D1D28230A04040405050505050508080F0F141F\r
+        253232323232323221212B2B3737374040404041414141454C41150308020202\r
+        0202020202030A0A0E1F1F2B3232323232323639394137374141413728284045\r
+        453B30364545371B07030C37413B3B3B3B3B3B3B3B3B3B414141414141414141\r
+        3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B373728281C1C1010100B0B0B0B\r
+        0B0B0B0B0B101010101013131313131313131313130E0E0E0E0E0E0E18181B1B\r
+        1B1B2B2B0C040404050505050404040808131414212121323232323232323131\r
+        373737373939393D3D3D374545451B030303030302020202020808080C131F1F\r
+        252532323236393941373741413B3B3B37232B2B2B3940404141414127151834\r
+        3D3B3B3B3B3B41414141414141414141414141413B3B3B3B3B3B3B3B3B3B3B3B\r
+        3B3B3B3B3B3B3B313128281C1C1010100B0B0B0B0B0B0B0B0B10101018181818\r
+        181313131313131313130E0E0E0E181818182323232323281504040405050505\r
+        04040404080F14141F252532323232322B3037373737373737373D4545454539\r
+        393924030101030303030303030A03030A131F1F3232343436363B3B3B373741\r
+        413737373737271D131F3636414141373737283434373B3B3B3B414141414141\r
+        41414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B313128281C\r
+        1C1010100B0B0B0B0B0B0B0B1010101018181818181813131313131313131313\r
+        13131818181823232323232318070404050505050404040409090F141F1F2525\r
+        252525253030303037373737373D3D45454545393939340C0101010102020202\r
+        040404040A131F1F32323236364545453939414137373737373737371B0D0D1F\r
+        2B3737373737373737373B3B3B3B3B3B3B3B3B3B414141414141414141414141\r
+        414141414141413B3B3B3B3B3B3B3B373728281C1C1010100B0B0B0B0B0B0B0B\r
+        1010101018181818181818181313130E0E0E0E0E0E0E18181818232323232323\r
+        230C0304040404040404040808080D131F1F1F25252525303030303037373737\r
+        3D3D3D3D45454530243440270303030303030303080404040A131F2424323234\r
+        3D4949403945453B3B3B3B2C2C37373737180E18181830373737373737373B3B\r
+        3B3B3B3B3B4141414141414141414141414141414141414141413B3B3B3B3B3B\r
+        3B3B3B313128281C1C1010100B0B0B0B0B0B0B0B101010101818181818181813\r
+        13130E0E0E0E0E0E0E0E0E1D1D1D1D1D1B1B1B24341803030505050404040408\r
+        0808080F1F1F1F252525303030373737373737373D3D3D3D3939392314344A45\r
+        1807070404040404080404040A131F1F25253440454545394545453B3B3B3737\r
+        373737372834403B271B1D243437373737373B3B3B3B3B3B3B3B414141414141\r
+        414141414141414141414141413B3B3B3B3B3B3B3B3B37372828281C1C101010\r
+        0B0B0B0B0B0B0B0B1010101018181818181813131313131313130E0E0E0E0E1D\r
+        1D1D1D1D1D1D1D2434240A030404040404040408080D0D0D141F2525252B2B31\r
+        31373737373737373D3D3D3D3D45270E143445453B180E040404040404030303\r
+        0A131F1F323239454545373741413B3B3B3B3737373737373034393537373737\r
+        3030303B3B3B3B3B3B3B3B3B3B3B41414141414141414141414141414141413B\r
+        3B3B3B3B3B3B3B3B3B3B37372828221C1C1010100B0B0B0B0B0B0B0B10101010\r
+        181818181818131313131313131313131313131D1D1D1D1D1D1D1D2424241808\r
+        0D08080404040408080D0D0D141F252525303030373737373737374545453439\r
+        45450C0C2539454545370E0404040404040303030A131F1F3234393945453741\r
+        4137373737373737373737373939373737373737373737373B3B3B3B3B3B3B3B\r
+        4141414141414141414141414141414141414141414141414141414141373737\r
+        2828221C1C1010100B0B0B0B0B0B0B0B10101010181818181813131313131313\r
+        1818181818181818241D1D1D1D1D181F2424240E0E0808080808080808080D0D\r
+        141F2525253030373737373737374545453039454528030C344040454545300A\r
+        03030303030303070C181F252534394141414141373737373737373737373737\r
+        3939353535373737373737373B3B3B3B3B414141414141414141414141414141\r
+        414141414141414141414141413B3B3B3B3B37372727221C1C1010100B0B0B0B\r
+        0B0B0B0B10101010181818180E0E1818180E0E0E181818181818181824241818\r
+        18180E1F2424241D0E0808080808080808080D0D141F1F253030303737373737\r
+        3737454539394545450C010E40404040454545240A0A0A0A0A0A0A0E181F2525\r
+        2539414141373737373737373737373737373737343737373535353737373737\r
+        373B3B3B3B414141414141414141413B3B3B4141414141414141413B3B3B3B3B\r
+        3B3B3B3B3B3B37372828281C1C1010100B0B0B0B0B0B0B0B1010101018181818\r
+        180E0E181813131313131D181818181824241D1D1D150A1F2424242418180A04\r
+        040404040A0A0D0D141F21253030303737373737373D3D33394545453007010A\r
+        394C45394545454524130E0E0E0E18181F1F1F323445454530303737373B3B3B\r
+        3737373737373734343535373737373737373737373B3B3B4141414141414141\r
+        414141414141414141414141414141413B3B3B3B3B3B3B3B3B3B3B313128281C\r
+        1C1C10100B0B0B0B0B0B0B0B0B10101018181818181313131313131313131D1D\r
+        181818181D241D1D1D0C08182424242424241304040404080A0A0A0E141F2525\r
+        303030373737373737373739454545451B030303234C4C393945454C43211414\r
+        1F1F1F1F1F1F1F2B344545373737373741414137373737373737373230353737\r
+        37373737373737373B3B3B414141414141414141414141414141414141414141\r
+        41414141413B3B3B3B3B3B3B3B3B3B313128221C1C1010100B0B0B0B0B0B0B0B\r
+        0B1010101818181813131313131313131818181818181D1D1D1D1D1D1D0A040E\r
+        1D1D1D2424242413080808080808080D141F252B2B2B30373737373737373745\r
+        454545450E0404010C404F453945454C442F251F1F1F1F1F1F1F1F3239393939\r
+        393B3B3B45453B37373737303030303230303737373737373737373737373741\r
+        414141414141414141414141414141414141414141414141414141413B3B3B3B\r
+        3B3B3B37372822221C1010100B0B0B0B0B0B0B0B0B1010101018181813131313\r
+        131313131313131D1D1D1D1D1D1D241D180A0408132323242423232F25130D0D\r
+        0D0D0D0D131F252B2B2B39373737373737373D3D3D3D45450E040404011D4C4C\r
+        45394545464E462B1F1F1F1F1F1F1F34404039393B3B3B3B3B45453737373728\r
+        2828252B2B35373737373737373B3B3B3B3B3B3B3B3B454545453B3B3B3B4141\r
+        414141414141414141414141414141413B3B3B3B3B3B3B373728281C1C101010\r
+        0B0B0B0B0B0B0B0B0B100E0E0E0E0E0E13131313131313131313181D1D1D1D1D\r
+        1D1D2424180A08080F1D1D1D24242444482B131313131313131F252B2B2B2B39\r
+        37373737373D3D3D3D3D45370A0404040107304C454545454D4D4A452B1F1F1F\r
+        1F1F1F34454531313B3B3B3B373737373737372727272430373737373737373B\r
+        3B3B3B3B3B3B3B4141414141413B3B3B3B3B4141414141414141414141414141\r
+        414141413B3B3B3B3B3B3B373728281C1C1C10100B0B0B0B0B0B0B0B0B0E1010\r
+        10101313131313131313131313131D1D1D1D1D1D1D1D2424130808080D1F1F23\r
+        2324244E4E24242414141414141424302828283737373737373B454545454530\r
+        0704040404040E344C4530344B4D454545341F141F1F1F3445453037373D3D37\r
+        3737373737372727272730303737373737373B3B3B3B3B3B3B3B3B3B3B414141\r
+        3B3B3B3B3B3B3B3B3B3B4141414141414141414141414141413B3B3B3B3B3B37\r
+        3728281C1C1C12120B0B0B0B0B0B0B0B0B0E1010101010101018181818181818\r
+        1D1D1D1D1D1D1D1D1D1D24240E08080808131D242418364E401B1B24241F1414\r
+        141F253030303030303939393B3B454545454530070404040404041330454543\r
+        434537404045341F1F1F253445303039414141413B3737373727272727272737\r
+        37373737373B3B3B3B3B3B3B3B4141413B3B3B3B3B3B3B3B3B3B3B3B3B414141\r
+        414141414141414141414141413B3B3B3B3B3B31313122221C1C12120B0B0B0B\r
+        0B0B0B0B0B1010101818181818131313131D1D1D1D1D1D1D1D1D1D1D1D1D1D1D\r
+        0C0404080808132424244848281B2330302B1F14141F25303030303030393B3B\r
+        3B3B4545454545280A05050504040404132439434D454545454545392B1F1F32\r
+        30303D3D3D3D3D3D3D3D37372727272727272737373737373737413B3B3B3B3B\r
+        3B4141413B3B3B3B3B3B3B3B4141414141414141414141414141414141414141\r
+        3B3B3B3B3B3B3B313128281C1C1C10100B0B0B0B0B0B0B0B0B10101010181818\r
+        18181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D1D0E04040909080D1425344439\r
+        2728282828282424241F1F2B2B2B2B343439393939394545454545310A040404\r
+        0404080808131F32404545454545454949372B25343441414141414141413737\r
+        3737372727272730303030373737413B3B3B3B3B3B3B41414141413B3B3B3B41\r
+        41414141414141414141414141414141414141413B3B3B3B3B3B37373728281C\r
+        1C1C10100B0B0B0B0B0B0B0B101010101018181818181D1D1D1D1D1D1D1D1D1D\r
+        1D1D1D1818181818180808080808080D131F322B2B393928282828282824242B\r
+        2B2B2B393939393939454545454545370C0404040404040404040F1D25343439\r
+        39454545454545344343394545454545453B3B37373737372C2C2C2C2C2C2C37\r
+        37373B3B3B3B3B3B3B3B41414141414141414141414141414141414141414141\r
+        4141414141414141413B3B3B3B3B37373728281C1C1C10100B0B0B0B0B0B0B10\r
+        10101010181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1818181818180D0808\r
+        080808080E0E1F25252534343028282828283434342430393939394545454545\r
+        4545453B0E0404090904040404040A131F1F25343440404040404040404D4545\r
+        4545454541414141413737373737373727272737373737373B3B3B3B3B3B3B3B\r
+        3B3B3B3B3B4141413B3B3B4141414141414141414141414141413B3B3B3B3B3B\r
+        3B3B37373728281C1C1C10100B0B0B0B0B0B0B10101010101A1A1D1D1D1D1D1D\r
+        1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D0D0808080808080D0D131F1F252534\r
+        3434343434343434342B2B373737373745454545454545452304040804040404\r
+        0404040A141F25253236363636363645454545454545454541414141413B3737\r
+        3737313131303030373737373B3B3B3B3B3B3B3B3B3B3B3B4141413B3B3B4141\r
+        414141414141414141414141413B3B3B3B3B373737373131313122221C1C1010\r
+        0B0B0B0B0B0B0B0B0B0E10101010101010181818181818181D1D1D1D1D1D1818\r
+        18232323230E090909090909090A0E1F1F323232323232323232303030393737\r
+        373737373D4545454545454530070404090404040404040A131F252532323636\r
+        364045454545454545454545454141413B3B3B3B373737373737373737373737\r
+        373B3B3B3B414141414141414141414141414141414141414141414141373737\r
+        3737373535353535353531313128281C1C1C10100B0B0B0B0B0B0B0B0B101010\r
+        1818181818131313131D1D1D1D1D1D1D1D1D1D1D1D232323230E080909090909\r
+        09090E141F25323232323232343737373737373737373D3D3D45454545454545\r
+        370C040408080404040404040D141F2525323636404041414141414545454545\r
+        45454545453B3B3B3B3B3B3B3B3737373737373737373B3B3B3B414141414141\r
+        4141413B3B3B3B3B3B3B3B3B3B3B3B3B3B353535353535353535353535353535\r
+        2828281C1C1C10100B0B0B0B0B0B0B0B0B1010101018181818181818181D1D1D\r
+        1D1D1D1D1D1D1D1D1D23232323230E050808080808080D131F1F252525252534\r
+        373737373B3B3B3D3D3D3D3D3D3D45454141414145300A040409090505050508\r
+        08131F1F253434344545454545454541414141454545454545413B3B3B3B3B3B\r
+        3B3B3B3B3B3535373737373737373737414141413B3B3B3B3B3B3B3B3B3B3737\r
+        3737353535353535353535353535353535313131272722221C1C10100B0B0B0B\r
+        0B0B0B0B101010101018181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D23\r
+        232323090909090909090909131F2525252534393737373737373D3D3D3D3D3D\r
+        3D3D3D4545454545454527080509090404040404040A18243236364545454545\r
+        453B3B3B3B3B45454545454545453B3B3B3B3B3B3B3B3B373737373737373737\r
+        373737373737413B3B3B3B3B3B3B3B3B3B353535353535353535272727272735\r
+        352C2C2C2C2C2C2C2C2222221C1C12120B0B0B0B0B0B0B101010101018181818\r
+        1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D232323301D0A0808080808080D\r
+        131F1F252525393939373737373D3D3D45454545454545454545454545454523\r
+        080505040404040404040E1D32364041413D3D3D3B3B3B3B3B3B454545454545\r
+        45453B3B3B373737373737373737373737373737373737373737373737373737\r
+        3737373737372C2C272727272727272727272727272727272727272722222222\r
+        1C1C12120B0B0B0B0B0B0B0B0B0B10101A1A1D1D1D1D1D1D1D1D1D1D1D1D1D1D\r
+        1D1D1D1D1D1D1D23232323301D0A040409090909131A1A212530373737373737\r
+        3939393939454545454545454545454545454545230804040404040404040A14\r
+        253645454545453B3B3B414141414545454545414141413B3B3B3B3B3B3B3B3B\r
+        37373737373737373737373737373535352C2C2C2C2C2C2C2C27272727272727\r
+        272727272727272727272727272727272727221C1C1C10100B0B0B0B0B0B0B0B\r
+        0B0B101018181D1D1D1D1D1D1D1D1D1D1D1D181818181D1D1D1D1D2323232330\r
+        30230F08080808080D131F252537373737373737373737373D3D454545454545\r
+        454545454545454545230A040404040404040A14254045454545373737414141\r
+        41414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B37373737373737373535\r
+        3535353535272727272727272727272727272727272727272727272727272727\r
+        2727272727271C1C1C1C10100B0B0B0B0B0B0B0B0B0B0B0B0E10101010101010\r
+        181818181818181D1D1D1D1D1D1D1D282828232328343E1F0A0808080D131F32\r
+        3937373737373737373737373D3D4545454545454545454545454545454C300D\r
+        0404040404040413344545454545373737373D4141413B3B3B3B3B3B3B3B3B3B\r
+        3B3B3737373B3B3B3B3B3B373737373737373535353535353535272727272727\r
+        2727272727272727272727272720202020272727272727272727221C1C1C1010\r
+        0B0B0B0B0B0B0B0B0B0B0B0B1010101818181818131313131D1D1D1D1D1D1D1D\r
+        1D1D232323282828282F4B4F390E04040A131F343939393939393B3D3D3D3D3D\r
+        3D3D45454145454545454545454545454545422F18040404040404133445453B\r
+        3B3737373737373D3D3D3D3D3D37373737373737373737373737373737373737\r
+        3737373737373737373737272727272727272727272727272727272727272727\r
+        272727272727272727313131313122221C1C12120B0B0B0B0B0B0B0B0B0B0B0B\r
+        1010101018181818181818181D1D1D1D1D1D1D1D1D1D2323233030272B424E57\r
+        57371B0A0A0A1F3439393939393B3D3D3B3D3D3D3D3D3D3D4545414545454539\r
+        4545454545403C44451B07040404040E34454537373737373737373737373737\r
+        3737373737373737373737373737373737373737373737373737373737373727\r
+        2727272723232323232727272727272727272C2C2C2C2C2C3535353537373737\r
+        3728281C1C1C12120B0B0B0B0B0B0B0B0B0B0B101010101018181818181D1D1D\r
+        1D1D1D1D1D1D1D2323231D1D23454545394242494545454515070F3439393939\r
+        39393D3D3D3D3D3D3D3D3D3D3D45454541454545454545454543424D4A453115\r
+        0404040E303D3D3D3D3737373737373737373737373737373737373737373737\r
+        3737373737373535353535353535353535352727232323232323232323232323\r
+        23232323232C2C3737373737373737373B3B3B373728281C1C1C12120B0B0B0B\r
+        0B0B0B0B0B0B1010101010181818181D1D1D1D1D1D1D1D1D1D1D1D2323233939\r
+        394545392F424D41414141415E39183239373737373939393D3D454545454545\r
+        4545454545454545454545454543424D4545453B230A030A303D3D3D3D373737\r
+        3737373737373737373737373737373737373737373737373737372727272727\r
+        27272727272723232323232323232323232323232323232323232C2C37373737\r
+        3B3B3B3B3B3B3B3B313122221C1C10100B0B0B0B0B0B0B0B0B0B10101010101A\r
+        1A1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D233434342424303E48454545453B3B\r
+        3737373739393937373737373939394545454545454545454540454545454545\r
+        394242494545454545371B1B3440403737373731313131313137373737373737\r
+        3737373737372727272727272727272727272727272727272723232323232323\r
+        2323231B1B1B1B1B1B1B1B1B1B2727272737373737413B3B3B3B3B3B31312222\r
+        1C1010100B0B0B0B0B0B0B0B0B0B0B0E10101010101010181818181818181D1D\r
+        1D1D1D1D1D232323301313323224394F453B3737373737373737373737373737\r
+        37373D3D454545454545454545393939394545392F424D414141414141414137\r
+        3434373737373737373737373535353537373737373737373727272727272727\r
+        2727272727272727272727272723232323232323231B1B1B1B1B1B1B1B232323\r
+        23272727353737373B3B3B3B3B3B3B313128281C1C10100B0B0B0B0B0B0B0B0B\r
+        0B0B0B10101018181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D2323232345241A\r
+        130D2556453B3B3737373737373737373737393939373D3D4545454545454545\r
+        453D3434342424303E48454545453B3B3B3B3B3B303030302727272730303030\r
+        3030272737373737373737272727272727272727232323232727272723232323\r
+        231B1B1B1B1B1B1B1B1B1B1B1B1B1B1B2323232727272735373737373B3B3B3B\r
+        373737372828281C1C1010100B0B0B0B0B0B0B0B0B0B0B10101010181818181D\r
+        1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D23234545321A252D2D2B2B343737373737\r
+        393937373737373739393D3D454545454545454545454545301313323224394F\r
+        453B373737373728283131312727272727272727272727272727272727313127\r
+        27272727272723232323232323232323232323231B1B1B1B1B1B1B1B1B1B1B1B\r
+        1B1B1B232323272727272735373737373B3B3B37373737372828281C1C101010\r
+        0B0B0B0B0B0B0B0B0B0B1010101818181818131313131D1D1D181818181D1D1D\r
+        1D1D23232345454246464B3E2824242437373737373737373737373737373939\r
+        3945454545454541454545454545241A130D2556453B3B373737373737372C27\r
+        27272723232323232323232323232323232C2C2C272323232323232323232323\r
+        23232323231B1B1B1B1B1B1B1B1B1B1B1B1B1B23232323232323232727272727\r
+        3737373737373737373737373728281C1C1010100B0B0B0B0B0B0B0B0B0B1010\r
+        10101818181818181818181818181D1D1D1D1D1D1D1D2828284539424D494545\r
+        3B3B3030373737373737373737393939373737373D3D45454545454545454545\r
+        454545321A252D2D2B2B34373728282828282827272727272323232323232323\r
+        2323232323232727272323232323232323232323231B1B1B1B1B1B1B1B1B1B1B\r
+        1B1B1B1B1B1B1B23232323232323232323232335353535353535353535353535\r
+        3528281C1C1010100B0B0B0B0B0B0B0B0B101010101018181818181D1D1D1D1D\r
+        1D1D1D1D1D1D1D1D1D23232328453E4345453B3B3B3B3B373737373739393937\r
+        37373737393939373D3D454545454545454545454545454246464B3E28242424\r
+        34343030303030303027272727272727232323232323231B1B1B232323232323\r
+        23232727272723232323231B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B2323232727\r
+        27272727272735353535353535353535353737373728281C1C1010100B0B0B0B\r
+        0B0B0B0B0B10101010181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D232323\r
+        45453E46453B3B3B3737373737373737373737373737373737373739453D3D3D\r
+        3D3D3D4545454545454539424D4945453B3B3030343434313131313131303030\r
+        30303027272323231B1B1B1B1B1B1B1B1B1B1B1B1B1B27272727272323232323\r
+        1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B2327272727272727272735353535353535\r
+        35353535353535353128281C1C10100B0B0B0B0B0B0B0B0B0B0B0B10101A1A1D\r
+        1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D23232323233D383E403D3D3D3D37373737\r
+        37373737373737373737373737373737373D3D45454545454545454545453E43\r
+        45453B3B3B3B3B3737373737373737373737373737372827272723232323231B\r
+        1B1B1B1B1B1B23232323232323272727272323232323231B1B1B1B1B1B1B1B1B\r
+        232323272727272727272735353535353535353535353535353535352828281C\r
+        1C1C100B0B0B0B0B0B0B0B0B0B0B0B101018181D1D1D1D1D1D1D1D1D1D1D1D1D\r
+        1D1D1D2323232828373636393939393131282828373737313131313131313131\r
+        3131282828393939454545454545454545453E46453B3B3B3737373737373737\r
+        3737373737373737373737282828232323232323232323232323232323232323\r
+        2727272727272323232323231B1B1B1B1B1B1B1B232323232727272727272727\r
+        2727272727272C2C2C2C3737313131272222221C1C10100B0B0B0B0B0B0B0B0B\r
+        0B0B0B101010181818181010101818181D1D1D1D1D1D1D1D2323282828252828\r
+        282828282828282828282828282828282828282828282828282828283D45453D\r
+        3D3D3D3D3D383E403D3D3D3D3737373731313131313131313131312828282828\r
+        2823232323232323232323232323232323232727272727272727272323232323\r
+        231B1B1B1B1B1B1B232323232727272727272727272727272727272727353535\r
+        3535272727271B1B1010100B0B0B0B0B0B0B0B0B0B0B0B101010101818181818\r
+        18131D1D1D1D1D1D1D1D1D1D2828222222252222222222222222222228282828\r
+        282823232323222828282828282323233D454539373737373736363939393931\r
+        3128282828282828282828282828282823232323231B1B1B1B1B1B1B1B232323\r
+        23232323272727272727272727272323232323231B1B1B1B1B1B1B1B1B1B2727\r
+        272727272727272727272727272727273131313131312727271B1B1B1010100B\r
+        0B0B0B0B0B0B0B0B0B0B101010181818181823231B1B1B1B1B1B1B1B1B1B1B1B\r
+        28281C1C1C1C1C1C1C1C1C1C1C1C1C1C22222222221B1B1B1B1B1C2222222228\r
+        282828282828282828312828282528282828282828282828282828232323231B\r
+        1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B22222828282828282828\r
+        282323231B1B1B1B1B1B1B1B1B1B1B1B1B222828282828282828282828282828\r
+        2828282831313128282828281C1C1C1C1010100B0B0B0B0B0B0B0B0B0B0B1010\r
+        1010181818181B1B1B1B1B1B1B18181818181818232323231B1B1B1B1B1B1B1B\r
+        1B1B1B1B1C1C1C1B1B1B18181818181818181822282828282828232323222222\r
+        22252222222222222222222222221B1B1B1B1B1B1B1B1B1B1818181818181818\r
+        181B1B1B1B1B1B1B2222222222222222222222222222221B1B1B1B1B1B181818\r
+        18181C2222222228282828282828282828282828282828282828282822222222\r
+        1C1C1C1C1010100B0B0B0B0B0B0B0B0B0B101010101018181818181818181818\r
+        18181818181818181B1B1B1B1B1B1B1B1B181818181818181010101010101010\r
+        101010101010181C22222222221B1B1B1B1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C\r
+        1B1B1B1818181818181818181818181818181818181B1B1B1B1B1B1B1B222222\r
+        22222222222222221C1C1C1C1C1B1B1B181818181C1C1C1C2222222222222222\r
+        2222222222222222222222222222222222221C1C1C1C1C1010100B0B0B0B0B0B\r
+        0B0B0B0B0B10101010181818181D101010101010101010101010101018181818\r
+        1818181818181818181818181010101010101010101010101010181818181D24\r
+        1D1D101C1C1C1C1C1A1A10101010101010101010101010101010101010101010\r
+        101010101010101010101B1B1B1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C\r
+        1C1C1C1C1C101010101C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C\r
+        1C1C1C1C1C1C1C1C1C1C101010100B0B0B0B0B0B0B0B0B0B0B0B0B10101A1A1D\r
+        1D1D101010101010101010101010101010101010101010101010101010101010\r
+        10101010101010101010101010101010101010101010101C1010101010101010\r
+        1010101010101010101010101010101010101010101010101010101010101010\r
+        10101C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1010101010101010101C\r
+        1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1010101010\r
+        100B0B0B0B0B0B0B0B0B0B0B0B0B0B101018181D1D1D10101010101010101010\r
+        1010101010101010101010101010101010101010101010101010101010101010\r
+        1010101010101010101010101010101010101010101010101010101010101010\r
+        1010101010101010101010101010101010101010101010101010101010101010\r
+        1010101010101010101010101010101010101010101010121212121212121212\r
+        12121210101010101010101010101010101010100B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0E1010101010101010101010101010101010101010101010101010\r
+        10101010101010100B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B12\r
+        1212121210101010101010101010101010101010101010101010101010101010\r
+        1010101010101010101010101010101010101010101010101010101010101010\r
+        1010101010101010101010101010101010101010101010101010101010101010\r
+        1010101010100B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B101010101010101010101010100B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\r
+        0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B}\r
+      Stretch = True\r
+      IsControl = True\r
+    end\r
+  end\r
+  object tmrAboutBox: TTimer\r
+    Enabled = False\r
+    Interval = 5000\r
+    OnTimer = tmrAboutBoxTimer\r
+    Left = 293\r
+    Top = 12\r
+  end\r
+end\r
diff --git a/win32/gui/AboutDialogU.pas b/win32/gui/AboutDialogU.pas
new file mode 100644 (file)
index 0000000..e5db993
--- /dev/null
@@ -0,0 +1,67 @@
+unit AboutDialogU;\r
+\r
+interface\r
+\r
+uses\r
+       Buttons, Classes, Controls, Dialogs, ExtCtrls, Forms, Graphics, Messages, StdCtrls, SysUtils, Windows,\r
+       VersionInfo;\r
+\r
+type\r
+       TAboutBox = class (TForm)\r
+               private // invisible outside of the unit\r
+               protected // visible in the unit and in descended classes\r
+               public // visible wherever the class can be referenced\r
+               published // like public, but generates RTTI info\r
+                       lblCopyright: TLabel;\r
+                       lblLicense: TLabel;\r
+                       lblProductName: TLabel;\r
+                       lblVersion: TLabel;\r
+\r
+                       pnlInner: TPanel;\r
+                       pnlOuter: TPanel;\r
+                       ProgramIcon: TImage;\r
+\r
+                       tmrAboutBox: TTimer;\r
+\r
+                       procedure FormCreate (Sender: TObject);\r
+                       procedure FormShow (Sender: TObject);\r
+                       procedure tmrAboutBoxTimer (Sender: TObject);\r
+       end;\r
+\r
+var\r
+       AboutBox: TAboutBox;\r
+\r
+implementation\r
+\r
+{$R *.DFM}\r
+\r
+procedure TAboutBox.FormCreate (Sender: TObject);\r
+var s: string;\r
+begin\r
+       lblCopyright.Caption   := GetVersionString ('LegalCopyright');\r
+       lblLicense.Caption     := GetVersionString ('License');\r
+       lblProductName.Caption := GetVersionString ('ProductName');\r
+       Caption                := lblProductName.Caption;\r
+       lblVersion.Caption     := lblVersion.Caption + GetFileVersion (TFileVersionLong);\r
+\r
+       ShortDateFormat := 'yyyy';\r
+       s := DateToStr (Date);\r
+       if s <> Copy (lblCopyright.Caption, Length(lblCopyright.Caption)-3,4) then // year of original copyright\r
+               lblCopyright.Caption := lblCopyright.Caption + ', ' + s;\r
+end;\r
+\r
+procedure TAboutBox.FormShow (Sender: TObject);\r
+begin\r
+       tmrAboutBox.Enabled := true;\r
+end;\r
+\r
+procedure TAboutBox.tmrAboutBoxTimer (Sender: TObject);\r
+begin\r
+       tmrAboutBox.Enabled := false;\r
+       AboutBox.Visible := false;\r
+end;\r
+\r
+initialization\r
+end.\r
+\r
+\r
diff --git a/win32/gui/GPSBabelGUI.cfg b/win32/gui/GPSBabelGUI.cfg
new file mode 100644 (file)
index 0000000..9d13f67
--- /dev/null
@@ -0,0 +1,38 @@
+-$A8\r
+-$B-\r
+-$C+\r
+-$D+\r
+-$E-\r
+-$F-\r
+-$G+\r
+-$H+\r
+-$I+\r
+-$J-\r
+-$K-\r
+-$L+\r
+-$M-\r
+-$N+\r
+-$O+\r
+-$P+\r
+-$Q-\r
+-$R-\r
+-$S-\r
+-$T-\r
+-$U-\r
+-$V+\r
+-$W-\r
+-$X+\r
+-$YD\r
+-$Z1\r
+-cg\r
+-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+-H+\r
+-W+\r
+-M\r
+-$M16384,1048576\r
+-K$00400000\r
+-LE"c:\program files\borland\delphi7\Projects\Bpl"\r
+-LN"c:\program files\borland\delphi7\Projects\Bpl"\r
+-w-UNSAFE_TYPE\r
+-w-UNSAFE_CODE\r
+-w-UNSAFE_CAST\r
diff --git a/win32/gui/GPSBabelGUI.dof b/win32/gui/GPSBabelGUI.dof
new file mode 100644 (file)
index 0000000..ba85469
--- /dev/null
@@ -0,0 +1,137 @@
+[FileVersion]\r
+Version=7.0\r
+[Compiler]\r
+A=8\r
+B=0\r
+C=1\r
+D=1\r
+E=0\r
+F=0\r
+G=1\r
+H=1\r
+I=1\r
+J=0\r
+K=0\r
+L=1\r
+M=0\r
+N=1\r
+O=1\r
+P=1\r
+Q=0\r
+R=0\r
+S=0\r
+T=0\r
+U=0\r
+V=1\r
+W=0\r
+X=1\r
+Y=1\r
+Z=1\r
+ShowHints=1\r
+ShowWarnings=1\r
+UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+NamespacePrefix=\r
+SymbolDeprecated=1\r
+SymbolLibrary=1\r
+SymbolPlatform=1\r
+UnitLibrary=1\r
+UnitPlatform=1\r
+UnitDeprecated=1\r
+HResultCompat=1\r
+HidingMember=1\r
+HiddenVirtual=1\r
+Garbage=1\r
+BoundsError=1\r
+ZeroNilCompat=1\r
+StringConstTruncated=1\r
+ForLoopVarVarPar=1\r
+TypedConstVarPar=1\r
+AsgToTypedConst=1\r
+CaseLabelRange=1\r
+ForVariable=1\r
+ConstructingAbstract=1\r
+ComparisonFalse=1\r
+ComparisonTrue=1\r
+ComparingSignedUnsigned=1\r
+CombiningSignedUnsigned=1\r
+UnsupportedConstruct=1\r
+FileOpen=1\r
+FileOpenUnitSrc=1\r
+BadGlobalSymbol=1\r
+DuplicateConstructorDestructor=1\r
+InvalidDirective=1\r
+PackageNoLink=1\r
+PackageThreadVar=1\r
+ImplicitImport=1\r
+HPPEMITIgnored=1\r
+NoRetVal=1\r
+UseBeforeDef=1\r
+ForLoopVarUndef=1\r
+UnitNameMismatch=1\r
+NoCFGFileFound=1\r
+MessageDirective=1\r
+ImplicitVariants=1\r
+UnicodeToLocale=1\r
+LocaleToUnicode=1\r
+ImagebaseMultiple=1\r
+SuspiciousTypecast=1\r
+PrivatePropAccessor=1\r
+UnsafeType=0\r
+UnsafeCode=0\r
+UnsafeCast=0\r
+[Linker]\r
+MapFile=0\r
+OutputObjs=0\r
+ConsoleApp=1\r
+DebugInfo=0\r
+RemoteSymbols=0\r
+MinStackSize=16384\r
+MaxStackSize=1048576\r
+ImageBase=4194304\r
+ExeDescription=\r
+[Directories]\r
+OutputDir=\r
+UnitOutputDir=\r
+PackageDLLOutputDir=\r
+PackageDCPOutputDir=\r
+SearchPath=\r
+Packages=vcl;rtl;vclx;indy;vclie;xmlrtl;inetdbbde;inet;inetdbxpress;dbrtl;soaprtl;dsnap;VclSmp;dbexpress;vcldb;dbxcds;inetdb;bdertl;vcldbx;adortl;teeui;teedb;tee;ibxpress;visualclx;visualdbclx;vclactnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclaxserver\r
+Conditionals=\r
+DebugSourceDirs=\r
+UsePackages=0\r
+[Parameters]\r
+RunParams=\r
+HostApplication=\r
+Launcher=\r
+UseLauncher=0\r
+DebugCWD=\r
+[Language]\r
+ActiveLang=\r
+ProjectLang=\r
+RootDir=\r
+[Version Info]\r
+IncludeVerInfo=1\r
+AutoIncBuild=0\r
+MajorVer=2\r
+MinorVer=0\r
+Release=0\r
+Build=0\r
+Debug=0\r
+PreRelease=0\r
+Special=0\r
+Private=0\r
+DLL=0\r
+Locale=1033\r
+CodePage=1252\r
+[Version Info Keys]\r
+CompanyName=Down East Engineering\r
+FileDescription=\r
+FileVersion=2.0.0.0\r
+InternalName=\r
+LegalCopyright=© Down East Engineering 2005\r
+LegalTrademarks=\r
+OriginalFilename=\r
+ProductName=GPSBabelGUI\r
+ProductVersion=2.0.0.0\r
+Comments=\r
+License=Subject to terms of the GNU General Public License\r
diff --git a/win32/gui/GPSBabelGUI.dpr b/win32/gui/GPSBabelGUI.dpr
new file mode 100644 (file)
index 0000000..b943c1f
--- /dev/null
@@ -0,0 +1,17 @@
+program GPSBabelGUI;\r
+\r
+{%ToDo 'GPSBabelGUI.todo'}\r
+\r
+uses\r
+  Forms,\r
+  GPSBabelGUIDialogU in 'GPSBabelGUIDialogU.pas' {GPSBabelGUIDialog},\r
+  AboutDialogU in 'AboutDialogU.pas' {AboutBox};\r
+\r
+{$R *.res}\r
+\r
+begin\r
+  Application.Initialize;\r
+  Application.Title := 'GPSBabelGUI';\r
+  Application.CreateForm(TGPSBabelGUIDialog, GPSBabelGUIDialog);\r
+  Application.Run;\r
+end.\r
diff --git a/win32/gui/GPSBabelGUI.ico b/win32/gui/GPSBabelGUI.ico
new file mode 100644 (file)
index 0000000..76a19fd
Binary files /dev/null and b/win32/gui/GPSBabelGUI.ico differ
diff --git a/win32/gui/GPSBabelGUI.res b/win32/gui/GPSBabelGUI.res
new file mode 100644 (file)
index 0000000..55edc41
Binary files /dev/null and b/win32/gui/GPSBabelGUI.res differ
diff --git a/win32/gui/GPSBabelGUI.todo b/win32/gui/GPSBabelGUI.todo
new file mode 100644 (file)
index 0000000..7c881ff
--- /dev/null
@@ -0,0 +1,28 @@
+{DONE : v02.00.00 Add About.}\r
+{DONE : v02.00.00 Add Exit button.}\r
+{DONE : v02.00.00 Add Help.}\r
+{DONE : v02.00.00 Add hotkeys for most common buttons.}\r
+{DONE : v02.00.00 Add timer to load formats after form is created.}\r
+{DONE : v02.00.00 Align controls on dialog.}\r
+{DONE : v02.00.00 Don't permit file processing unless GPSBabel is OK.}\r
+{DONE : v02.00.00 Evaluate need for memoStdErr vs. Message dialog.}\r
+{DONE : v02.00.00 Include all project management and Delphi project files in upload.}\r
+{DONE : v02.00.00 LoadFormatsFromGPSBabelExe: Delete unused AllocConsole.}\r
+{DONE : v02.00.00 LoadFormatsFromGPSBabelExe: don't continue if GPSBabel not found.}\r
+{DONE : v02.00.00 LoadFormatsFromGPSBabelExe: 'GPS file formats loaded from GPSBabel.exe.' doesn't get written.}\r
+{DONE : v02.00.00 Look for GPSBabel.exe before attempting to open it.}\r
+{DONE : v02.00.00 Modify to use input filename and output type to generate default output filename.}\r
+{DONE : v02.00.00 Output file dialog: fill in filename and filetype, if possible.}\r
+{DONE : v02.00.00 Port to Delphi 7.}\r
+{DONE : v02.00.00 Process: Delete unused AllocConsole.}\r
+{DONE : v02.00.00 Process: don't allow processing null, or undefined, files.}\r
+{DONE : v02.00.00 Process: handle cases where input/output file is a dir.}\r
+{DONE : v02.00.00 Remove unused console invocations.}\r
+{DONE : v02.00.00 Remove unused variable declarations.}\r
+{DONE : v02.00.00 Rewrite to eliminate 'exit;'.}\r
+{DONE : v02.00.00 Sort default file types by alpha; add sort routine: CANCELLED: placed in GPSBabel.}\r
+{TODO : v02.01.00 Add option to suppress 'internal'.}\r
+{TODO : v02.01.00 Add options for track and route support (-t/-r) for each format, only when available.}\r
+{TODO : v02.01.00 Add serial port support.}\r
+{TODO : v02.01.00 Add sticky output directory.}\r
+{TODO : v02.01.00 Improve menu presentation via 'gpsbabel -^2'.}\r
diff --git a/win32/gui/GPSBabelGUIDialogU.ddp b/win32/gui/GPSBabelGUIDialogU.ddp
new file mode 100644 (file)
index 0000000..4370276
Binary files /dev/null and b/win32/gui/GPSBabelGUIDialogU.ddp differ
diff --git a/win32/gui/GPSBabelGUIDialogU.dfm b/win32/gui/GPSBabelGUIDialogU.dfm
new file mode 100644 (file)
index 0000000..916e23b
--- /dev/null
@@ -0,0 +1,218 @@
+object GPSBabelGUIDialog: TGPSBabelGUIDialog\r
+  Left = 461\r
+  Top = 119\r
+  BorderStyle = bsDialog\r
+  Caption = 'GPSBabelGUI'\r
+  ClientHeight = 258\r
+  ClientWidth = 380\r
+  Color = clBtnFace\r
+  Font.Charset = DEFAULT_CHARSET\r
+  Font.Color = clWindowText\r
+  Font.Height = -11\r
+  Font.Name = 'MS Sans Serif'\r
+  Font.Style = []\r
+  OldCreateOrder = False\r
+  Position = poScreenCenter\r
+  DesignSize = (\r
+    380\r
+    258)\r
+  PixelsPerInch = 96\r
+  TextHeight = 13\r
+  object lblGPSBabelURI: TLabel\r
+    Left = 66\r
+    Top = 237\r
+    Width = 250\r
+    Height = 13\r
+    Anchors = [akLeft, akBottom]\r
+    Caption = 'GPSBabel: http://www.gpsbabel.org'\r
+  end\r
+  object lblInputFileName: TLabel\r
+    Left = 17\r
+    Top = 17\r
+    Width = 43\r
+    Height = 13\r
+    Alignment = taRightJustify\r
+    Caption = 'Input file:'\r
+  end\r
+  object lblOutputFileName: TLabel\r
+    Left = 9\r
+    Top = 97\r
+    Width = 51\r
+    Height = 13\r
+    Alignment = taRightJustify\r
+    Caption = 'Output file:'\r
+  end\r
+  object bvlGPSBabelURI: TBevel\r
+    Left = 0\r
+    Top = 222\r
+    Width = 380\r
+    Height = 4\r
+    Anchors = [akLeft, akBottom]\r
+  end\r
+  object lblOutputFormat: TLabel\r
+    Left = 25\r
+    Top = 73\r
+    Width = 35\r
+    Height = 13\r
+    Alignment = taRightJustify\r
+    Caption = 'Format:'\r
+  end\r
+  object lblInputFormat: TLabel\r
+    Left = 25\r
+    Top = 41\r
+    Width = 35\r
+    Height = 13\r
+    Alignment = taRightJustify\r
+    Caption = 'Format:'\r
+  end\r
+  object btnInputFileDialog: TSpeedButton\r
+    Left = 339\r
+    Top = 12\r
+    Width = 23\r
+    Height = 22\r
+    Glyph.Data = {\r
+      76010000424D7601000000000000760000002800000020000000100000000100\r
+      04000000000000010000120B0000120B00001000000000000000000000000000\r
+      800000800000008080008000000080008000808000007F7F7F00BFBFBF000000\r
+      FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00555555555555\r
+      5555555555555555555555555555555555555555555555555555555555555555\r
+      555555555555555555555555555555555555555FFFFFFFFFF555550000000000\r
+      55555577777777775F55500B8B8B8B8B05555775F555555575F550F0B8B8B8B8\r
+      B05557F75F555555575F50BF0B8B8B8B8B0557F575FFFFFFFF7F50FBF0000000\r
+      000557F557777777777550BFBFBFBFB0555557F555555557F55550FBFBFBFBF0\r
+      555557F555555FF7555550BFBFBF00055555575F555577755555550BFBF05555\r
+      55555575FFF75555555555700007555555555557777555555555555555555555\r
+      5555555555555555555555555555555555555555555555555555}\r
+    NumGlyphs = 2\r
+    OnClick = btnInputFileDialogClick\r
+  end\r
+  object btnOutputFileDialog: TSpeedButton\r
+    Left = 339\r
+    Top = 92\r
+    Width = 23\r
+    Height = 22\r
+    Glyph.Data = {\r
+      76010000424D7601000000000000760000002800000020000000100000000100\r
+      04000000000000010000120B0000120B00001000000000000000000000000000\r
+      800000800000008080008000000080008000808000007F7F7F00BFBFBF000000\r
+      FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333333333\r
+      333333FFFFFFFFFFFFF33000077777770033377777777777773F000007888888\r
+      00037F3337F3FF37F37F00000780088800037F3337F77F37F37F000007800888\r
+      00037F3337F77FF7F37F00000788888800037F3337777777337F000000000000\r
+      00037F3FFFFFFFFFFF7F00000000000000037F77777777777F7F000FFFFFFFFF\r
+      00037F7F333333337F7F000FFFFFFFFF00037F7F333333337F7F000FFFFFFFFF\r
+      00037F7F333333337F7F000FFFFFFFFF00037F7F333333337F7F000FFFFFFFFF\r
+      00037F7F333333337F7F000FFFFFFFFF07037F7F33333333777F000FFFFFFFFF\r
+      0003737FFFFFFFFF7F7330099999999900333777777777777733}\r
+    NumGlyphs = 2\r
+    OnClick = btnOutputFileDialogClick\r
+  end\r
+  object comboInput: TComboBox\r
+    Left = 64\r
+    Top = 37\r
+    Width = 300\r
+    Height = 21\r
+    Style = csDropDownList\r
+    ItemHeight = 13\r
+    TabOrder = 1\r
+  end\r
+  object eInput: TEdit\r
+    Left = 64\r
+    Top = 13\r
+    Width = 273\r
+    Height = 21\r
+    TabOrder = 0\r
+  end\r
+  object eOutput: TEdit\r
+    Left = 64\r
+    Top = 93\r
+    Width = 273\r
+    Height = 21\r
+    TabOrder = 2\r
+  end\r
+  object comboOutput: TComboBox\r
+    Left = 64\r
+    Top = 69\r
+    Width = 300\r
+    Height = 21\r
+    Style = csDropDownList\r
+    ItemHeight = 13\r
+    TabOrder = 3\r
+  end\r
+  object btnProcess: TButton\r
+    Left = 232\r
+    Top = 141\r
+    Width = 132\r
+    Height = 25\r
+    Caption = '&Process'\r
+    TabOrder = 5\r
+    OnClick = btnProcessClick\r
+  end\r
+  object cbIgnoreShort: TCheckBox\r
+    Left = 64\r
+    Top = 145\r
+    Width = 121\r
+    Height = 17\r
+    Caption = 'Ignore "short" names'\r
+    TabOrder = 4\r
+  end\r
+  object btnExit: TButton\r
+    Left = 319\r
+    Top = 184\r
+    Width = 45\r
+    Height = 25\r
+    Caption = 'E&xit'\r
+    TabOrder = 6\r
+    OnClick = btnExitClick\r
+  end\r
+  object btnAbout: TButton\r
+    Left = 64\r
+    Top = 184\r
+    Width = 45\r
+    Height = 25\r
+    Caption = '&About'\r
+    TabOrder = 7\r
+    OnClick = btnAboutClick\r
+  end\r
+  object btnIntro: TButton\r
+    Left = 149\r
+    Top = 184\r
+    Width = 45\r
+    Height = 25\r
+    Caption = '&Intro'\r
+    TabOrder = 8\r
+    OnClick = btnIntroClick\r
+  end\r
+  object btnUseDefaultOutput: TButton\r
+    Left = 64\r
+    Top = 117\r
+    Width = 114\r
+    Height = 19\r
+    Caption = '&Use Default Filename'\r
+    TabOrder = 9\r
+    OnClick = btnUseDefaultOutputClick\r
+  end\r
+  object btnHowTo: TButton\r
+    Left = 234\r
+    Top = 184\r
+    Width = 48\r
+    Height = 25\r
+    Caption = '&How to...'\r
+    TabOrder = 10\r
+    OnClick = btnHowToClick\r
+  end\r
+  object dlgOpenInput: TOpenDialog\r
+    Options = [ofEnableSizing]\r
+    Left = 363\r
+    Top = 9\r
+  end\r
+  object dlgSaveOutput: TSaveDialog\r
+    Left = 363\r
+    Top = 88\r
+  end\r
+  object TimerLoadFormats: TTimer\r
+    OnTimer = TimerLoadFormatsTimer\r
+    Left = 350\r
+    Top = 229\r
+  end\r
+end\r
diff --git a/win32/gui/GPSBabelGUIDialogU.pas b/win32/gui/GPSBabelGUIDialogU.pas
new file mode 100644 (file)
index 0000000..e60a410
--- /dev/null
@@ -0,0 +1,480 @@
+{\r
+  Copyright Â© Richard L Messeder, Down East Engineering, www.DownEastEngineering.com and others listed below\r
+  Delphi 5, 6 & 7 Version\r
+  v02.00.00 Add About.\r
+  v02.00.00 Add Exit button.\r
+  v02.00.00 Add Help.\r
+  v02.00.00 Add hotkeys for most common buttons.\r
+  v02.00.00 Add timer to load formats after form is created.\r
+  v02.00.00 Align controls on dialog.\r
+  v02.00.00 Don't permit file processing unless GPSBabel is OK.\r
+  v02.00.00 Evaluate need for memoStdErr vs. Message dialog.\r
+  v02.00.00 Include all project management and Delphi project files in upload.\r
+  v02.00.00 LoadFormatsFromGPSBabelExe: Delete unused AllocConsole.\r
+  v02.00.00 LoadFormatsFromGPSBabelExe: don't continue if GPSBabel not found.\r
+  v02.00.00 Look for GPSBabel.exe before attempting to open it.\r
+  v02.00.00 Modify to use input filename and output type to generate default output filename.\r
+  v02.00.00 Output file dialog: fill in filename and filetype, if possible.\r
+  v02.00.00 Port to Delphi 7.\r
+  v02.00.00 Process: Delete unused AllocConsole.\r
+  v02.00.00 Process: handle cases where input/output file is a dir.\r
+  v02.00.00 Process: don't allow processing null, or undefined, files.\r
+  v02.00.00 Remove unused console invocations.\r
+  v02.00.00 Remove unused variable declarations.\r
+  v02.00.00 Rewrite to eliminate 'exit;'.\r
+  v02.00.00 Sort default file types by alpha; add sort routine: CANCELLED: placed in GPSBabel.\r
+}\r
+{\r
+    Copyright (C) 2002 Josh M. McKee, mrsnazz@users.sourceforge.net\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+}\r
+\r
+{\r
+    1.0.2   JMc   - Added LoadFormats to call the new -^ switch, to dynamically\r
+                    load the supported GPSDataFormats from gpsbabel.exe.\r
+    1.0.1   JMc   - Switched to using AddFormat for populating the GPSDataFormats table\r
+                  - Updated GPSDataFormats table to include currently supported GPSDataFormats\r
+                  - Switched to using CreateProcess rather than WinExec, so that\r
+                    we can display data from stderr to the user.\r
+    1.0.0   JMc   First release\r
+}\r
+\r
+unit GPSBabelGUIDialogU;\r
+\r
+interface\r
+\r
+uses\r
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,\r
+  Buttons, ExtCtrls, StdCtrls, StrUtils;\r
+\r
+const\r
+  CR  = chr ($0D);\r
+  LF  = chr ($0A);\r
+  Tab = chr ($09);\r
+\r
+type\r
+  TGPSDataFormat = record\r
+    sType: string; // type to be passed to GPSBabel\r
+    sExt: string;  // default file extension\r
+    sDesc: string; // description of format\r
+  end;\r
+\r
+  TGPSBabelGUIDialog = class (TForm)\r
+    private // invisible outside of the unit\r
+      OKtoRun: boolean;\r
+      BytesRead: DWord;\r
+      Buffer: array [0..4095] of char;\r
+      BufferIndex, TokenIndex, nFormats: integer;\r
+      sCmd, sGPSBabelMsg, sIgnoreShort: string;\r
+      Tokens: array [0..2] of string;\r
+      GPSDataFormats: array of TGPSDataFormat;\r
+      hRead, hWrite: THandle;\r
+      ProcessInfo: TProcessInformation;\r
+      SecurityAttr: TSecurityAttributes;\r
+      StartupInfo: TStartupInfo;\r
+      procedure LoadFormatsFromGPSBabelExe;\r
+      procedure PopulateCombos;\r
+      procedure PopulateDialogs;\r
+    protected // visible in the unit and in descended classes\r
+    public // visible wherever the class can be referenced\r
+    published // like public, but generates RTTI info\r
+      btnAbout: TButton;\r
+      btnExit: TButton;\r
+      btnHowTo: TButton;\r
+      btnInputFileDialog: TSpeedButton;\r
+      btnIntro: TButton;\r
+      btnOutputFileDialog: TSpeedButton;\r
+      btnProcess: TButton;\r
+      btnUseDefaultOutput: TButton;\r
+      bvlGPSBabelURI: TBevel;\r
+      cbIgnoreShort: TCheckBox;\r
+      comboInput: TComboBox;\r
+      comboOutput: TComboBox;\r
+      dlgOpenInput: TOpenDialog;\r
+      dlgSaveOutput: TSaveDialog;\r
+      eInput: TEdit;\r
+      eOutput: TEdit;\r
+      lblGPSBabelURI: TLabel;\r
+      lblInputFileName: TLabel;\r
+      lblInputFormat: TLabel;\r
+      lblOutputFileName: TLabel;\r
+      lblOutputFormat: TLabel;\r
+      TimerLoadFormats: TTimer;\r
+\r
+      procedure TimerLoadFormatsTimer(Sender: TObject);\r
+      procedure btnAboutClick(Sender: TObject);\r
+      procedure btnExitClick(Sender: TObject);\r
+      procedure btnHowToClick(Sender: TObject);\r
+      procedure btnInputFileDialogClick (Sender: TObject);\r
+      procedure btnIntroClick(Sender: TObject);\r
+      procedure btnOutputFileDialogClick (Sender: TObject);\r
+      procedure btnProcessClick (Sender: TObject);\r
+      procedure btnUseDefaultOutputClick(Sender: TObject);\r
+    end;\r
+\r
+var\r
+  GPSBabelGUIDialog: TGPSBabelGUIDialog;\r
+\r
+implementation\r
+\r
+uses AboutDialogU;\r
+\r
+{$R *.dfm}\r
+\r
+procedure TGPSBabelGUIDialog.TimerLoadFormatsTimer (Sender: TObject);\r
+// This could have been in FormCreate, but this way the form is shown\r
+// before the 'formats loaded' message.\r
+begin\r
+  TimerLoadFormats.Enabled := false;\r
+  nFormats := 0;\r
+  LoadFormatsFromGPSBabelExe;\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.LoadFormatsFromGPSBabelExe;\r
+  procedure AddFormat (sType, sExt, sDesc: string);\r
+  begin\r
+    inc (nFormats);\r
+    // changes the size of the GPSDataFormats array\r
+    // initialized at nil, so the first pass sets it to 1 row, addressed as [0]\r
+    SetLength (GPSDataFormats, nFormats);\r
+\r
+    GPSDataFormats [nFormats-1].sType := sType; // [n-1] because array is zero-based\r
+    GPSDataFormats [nFormats-1].sExt := sExt;\r
+    GPSDataFormats [nFormats-1].sDesc := sDesc;\r
+  end;\r
+\r
+begin\r
+  sCmd := 'GPSBabel -^'; // internal gpsbabel command -^\r
+\r
+  SecurityAttr.nLength := sizeof (TSECURITYATTRIBUTES);\r
+  SecurityAttr.bInheritHandle := true;\r
+  SecurityAttr.lpSecurityDescriptor := nil;\r
+\r
+  OKtoRun := false;\r
+  if CreatePipe (hRead, hWrite, @SecurityAttr, 0) then begin\r
+    FillChar (StartupInfo, Sizeof (StartupInfo), #0);\r
+    StartupInfo.cb := Sizeof (StartupInfo);\r
+    StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;\r
+    StartupInfo.wShowWindow := SW_HIDE and SW_SHOWMINNOACTIVE;\r
+    StartupInfo.hStdInput := GetStdHandle (STD_INPUT_HANDLE);\r
+    StartupInfo.hStdOutput:= hWrite;\r
+    StartupInfo.hStdError := hWrite;\r
+\r
+    if FileExists ('GPSBabel.exe') then begin\r
+      if CreateProcess (\r
+        nil,                // lpApplicationName    // pointer to name of executable module\r
+        // sCmd includes both the exec name and the command line parms in this call\r
+        pchar (sCmd),       // lpCommandLine,       // pointer to command line string\r
+        nil,                // lpProcessAttributes, // pointer to process security attributes\r
+        nil,                // lpThreadAttributes,  // pointer to thread security attributes\r
+        true,               // bInheritHandles,     // handle inheritance flag\r
+        CREATE_NEW_CONSOLE, // dwCreationFlags,     // creation flags\r
+        nil,                // lpEnvironment,       // pointer to new environment block\r
+        nil,                // lpCurrentDirectory,  // pointer to current directory name\r
+        StartupInfo,        // lpStartupInfo,       // pointer to STARTUPINFO\r
+        ProcessInfo)        // lpProcessInformation // pointer to PROCESS_INFORMATION\r
+        then begin\r
+\r
+        while (WaitforSingleObject (ProcessInfo.hProcess, 0)) <> WAIT_OBJECT_0 do;\r
+\r
+        PeekNamedPipe (hRead, nil, 0, nil, @BytesRead, nil);\r
+        ReadFile (hRead, Buffer, 4096, BytesRead, nil);\r
+        // The data passed by GPSBabel.exe should exceed 1500 bytes, but this provides some slack.\r
+        // (v2.0.0) We're discussing the possibility of having some sort of byte count passed by gpsbabel,\r
+        // e.g., 'byte count=1234'; we could then check for 'byte count=', and if we don't get it\r
+        // then we know that there is an error.\r
+        if BytesRead > 1000 then begin\r
+          BufferIndex := 0;\r
+          TokenIndex := 0;\r
+          FillChar (Tokens, SizeOf(Tokens), 0);\r
+\r
+          // Process the buffer into Types, Extensions, and Descriptions\r
+          while BufferIndex < BytesRead do begin\r
+            if Buffer [BufferIndex] in [Tab,CR,LF] then // Tab between fields, CRLF between rows\r
+              inc (TokenIndex)\r
+            else\r
+              Tokens [TokenIndex] := Tokens [TokenIndex] + Buffer [BufferIndex];\r
+            if TokenIndex = 3 then begin\r
+              TokenIndex := 0;\r
+              inc (BufferIndex); // Because we point to CR and must skip the LF\r
+              AddFormat (Tokens[0], Tokens[1], Tokens[2]);\r
+              FillChar(Tokens, SizeOf (Tokens), 0);\r
+            end;\r
+            inc (BufferIndex);\r
+          end;\r
+\r
+          PopulateCombos;\r
+          PopulateDialogs;\r
+          OKtoRun := true;\r
+          MessageDlg ('GPS file formats loaded from GPSBabel.exe.', mtInformation, [mbOk], 0);\r
+        end // if BytesRead > 0\r
+        else begin\r
+          sGPSBabelMsg :=  copy (Buffer, 1, BytesRead);\r
+          MessageBox (0, pchar (sGPSBabelMsg),'GPSBabel Error', MB_OK);\r
+        end\r
+      end\r
+      else\r
+        MessageDlg ('Unable to execute GPSBabel.exe.', mtError, [mbOk], 0);\r
+    end\r
+    else\r
+      MessageDlg ('Can''t find GPSBabel.exe.', mtError, [mbOk], 0);\r
+\r
+    CloseHandle (hRead);\r
+    CloseHandle (hWrite);\r
+  end\r
+  else\r
+    MessageDlg ('Unable to create pipe!', mtError, [mbOk], 0);\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.PopulateCombos;\r
+var\r
+  i: integer;\r
+begin\r
+  for i:=0 to nFormats-1 do begin\r
+    comboInput.items.add (GPSDataFormats[i].sDesc);\r
+    comboOutput.items.add (GPSDataFormats[i].sDesc);\r
+  end;\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.PopulateDialogs;\r
+var\r
+  i: integer;\r
+begin\r
+  dlgOpenInput.Filter := '';\r
+  dlgSaveOutput.Filter := '';\r
+  for i:=0 to nFormats-1 do begin\r
+    if (GPSDataFormats[i].sExt<>'') then begin\r
+      dlgOpenInput.Filter := dlgOpenInput.Filter +\r
+        GPSDataFormats[i].sDesc + ' (*.' +\r
+        GPSDataFormats[i].sExt + ')|*.' +\r
+        uppercase (GPSDataFormats[i].sExt) + '|';\r
+\r
+      dlgSaveOutput.Filter := dlgSaveOutput.Filter +\r
+        GPSDataFormats[i].sDesc + ' (*.' +\r
+        GPSDataFormats[i].sExt + ')|*.' +\r
+        uppercase (GPSDataFormats[i].sExt) + '|';\r
+    end;\r
+  end;\r
+\r
+  dlgOpenInput.Filter := dlgOpenInput.Filter + 'All files (*.*)|*.*';\r
+  dlgSaveOutput.Filter := dlgSaveOutput.Filter + 'All files (*.*)|*.*';\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.btnAboutClick(Sender: TObject);\r
+begin\r
+  if AboutBox = nil then begin\r
+    Application.CreateForm (TAboutBox, AboutBox);\r
+    AboutBox.Left := (Screen.Width - AboutBox.Width) div 2;\r
+    AboutBox.Top := (Screen.Height - AboutBox.Height) div 2;\r
+  end;\r
+  AboutBox.Show;\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.btnExitClick (Sender: TObject);\r
+begin\r
+  Application.Terminate;\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.btnHowToClick(Sender: TObject);\r
+begin\r
+  MessageBox (0, PChar (\r
+    'Begin using GPSBabelGUI by:' +CR+\r
+    '    Defining an input file. If the file has an extension that' +CR+\r
+    '    GPSBabelGUI recognizes, the format will be automatically' +CR+\r
+    '    selected.' +CR+CR+\r
+    '    If the selected input file format is not correct, select the correct' +CR+\r
+    '    format from the Format dropdown list.' +CR+CR+\r
+    '    Select an output format.' +CR+CR+\r
+    '    Select Use Default Filename.' +CR+CR+\r
+    '        GPSBabelGUI will fill in the default output directory/filename' +CR+\r
+    '        using the input directory and filename. To change it, edit the' +CR+\r
+    '        name directly or use the Save As dialog.' +CR+CR+\r
+    '    Select any options for GPSBabel to use during processing.' +CR+CR+\r
+    '    Select Process.'\r
+  ), 'How To...', MB_OK);\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.btnInputFileDialogClick (Sender: TObject);\r
+var\r
+  sExt: string;\r
+  i: integer;\r
+begin\r
+  if OKtoRun then\r
+    if dlgOpenInput.Execute then begin\r
+      eInput.Text := dlgOpenInput.filename;\r
+      sExt := uppercase (ExtractFileExt (eInput.text));\r
+      for i := 0 to nFormats-1 do\r
+        if '.' + uppercase (GPSDataFormats[i].sExt) = sExt then\r
+          comboInput.ItemIndex := i;\r
+    end;\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.btnIntroClick(Sender: TObject);\r
+begin\r
+  MessageBox (0, PChar (\r
+    'GPSBabelGUI is simply a GUI front end for GPSBabel.exe.' +CR+CR+\r
+    'GPSBabelGUI''s only purpose is to make it easier to call' +CR+\r
+    'GPSBabel.exe, so it must be able to find it. The easiest' +CR+\r
+    'way for GPSBabelGUI to find GPSBabel.exe is for both of' +CR+\r
+    'them to be in the same directory.' +CR+CR+\r
+    'GPSBabelGUI will not permit any processing to take place' +CR+\r
+    'if there is an error during startup, or if it cannot find' +CR+\r
+    'GPSBabel.exe.' +CR+CR+\r
+    'There are 3 classes of messages to expect:' +CR+Tab+\r
+      '°Errors' +CR+Tab+\r
+      '°Warnings' +CR+Tab+\r
+      '°Information' +CR+CR+\r
+    '°If you receive an Error, such as ''GPSBabel can''t be found'',' +CR+\r
+    'something has gone seriously amiss and must be corrected' +CR+\r
+    'before trying to run GPSBabelGUI again.' +CR+CR+\r
+    '°Warnings simply indicate that you are trying to do something' +CR+\r
+    'out of order, such as attempting to Process before defining' +CR+\r
+    'an input or output file.' +CR+CR+\r
+    '°Information dialogs provide you with useful information, such' +CR+\r
+    'as letting you know that a conversion has completed.' +CR+CR+\r
+    'The About box displays copyright information for several seconds.'\r
+  ), 'Introduction', MB_OK);\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.btnOutputFileDialogClick (Sender: TObject);\r
+var\r
+  sExt: string;\r
+  i: integer;\r
+begin\r
+  if OKtoRun then begin\r
+    dlgSaveOutput.filename := eOutput.Text;\r
+    if dlgSaveOutput.Execute then begin\r
+      eOutput.Text := dlgSaveOutput.filename;\r
+      sExt := uppercase (ExtractFileExt (eOutput.text));\r
+      for i := 0 to nFormats-1 do\r
+        if '.' + uppercase (GPSDataFormats[i].sExt) = sExt then\r
+          comboOutput.ItemIndex := i;\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.btnProcessClick (Sender: TObject);\r
+var\r
+  f: file;\r
+begin\r
+  if OKtoRun then begin\r
+    if eInput.text <> '' then begin\r
+      if FileExists (eInput.text) then begin\r
+        if (comboInput.ItemIndex) > -1 then begin // Input type is selected\r
+          if ((eOutput.text <> '') and (not DirectoryExists (eOutput.text))) then begin\r
+            // The output file must exist, or else ExtractShortPathName will not function\r
+            if not FileExists (eOutput.text) then begin\r
+              system.assign (f, eOutput.text);\r
+              system.rewrite (f);\r
+              system.close (f);\r
+            end;\r
+\r
+            if (comboOutput.ItemIndex) > -1 then begin // Output type is selected\r
+              if cbIgnoreShort.checked then\r
+                sIgnoreShort := '-s'\r
+              else\r
+                sIgnoreShort := '';\r
+\r
+              // Construct the command line to execute gpsbabel.exe. ExtractShortPathName\r
+              // is used to reduce any "long" file/directory names in the paths down to\r
+              // 8.3 dos format names (this removes spaces, etc).\r
+              sCmd := 'GPSBabel '+sIgnoreShort // +'-i garmin -f usb:' // for testing\r
+                +' -i ' + GPSDataFormats [comboInput.ItemIndex].sType\r
+                +' -f ' + ExtractShortPathName (eInput.text)\r
+                +' -o ' + GPSDataFormats [comboOutput.ItemIndex].sType\r
+                +' -F ' + ExtractShortPathName (eOutput.text);\r
+\r
+              SecurityAttr.nLength := sizeof (TSECURITYATTRIBUTES);\r
+              SecurityAttr.bInheritHandle := true;\r
+              SecurityAttr.lpSecurityDescriptor := nil;\r
+\r
+              if CreatePipe (hRead, hWrite, @SecurityAttr, 0) then begin\r
+                FillChar (StartupInfo, Sizeof (StartupInfo), 0);\r
+                StartupInfo.cb := Sizeof (StartupInfo);\r
+                StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;\r
+                StartupInfo.wShowWindow := SW_HIDE and SW_SHOWMINNOACTIVE;\r
+                StartupInfo.hStdInput := GetStdHandle (STD_INPUT_HANDLE);\r
+                StartupInfo.hStdOutput:= hWrite;\r
+                StartupInfo.hStdError := hWrite;\r
+\r
+                if CreateProcess (\r
+                  nil,                // lpApplicationName    // pointer to name of executable module\r
+                  // sCmd includes both the exec name and the command line parms in this call\r
+                  pchar (sCmd),       // lpCommandLine,       // pointer to command line string\r
+                  nil,                // lpProcessAttributes, // pointer to process security attributes\r
+                  nil,                // lpThreadAttributes,  // pointer to thread security attributes\r
+                  true,               // bInheritHandles,     // handle inheritance flag\r
+                  CREATE_NEW_CONSOLE, // dwCreationFlags,     // creation flags\r
+                  nil,                // lpEnvironment,       // pointer to new environment block\r
+                  nil,                // lpCurrentDirectory,  // pointer to current directory name\r
+                  StartupInfo,        // lpStartupInfo,       // pointer to STARTUPINFO\r
+                  ProcessInfo)        // lpProcessInformation // pointer to PROCESS_INFORMATION\r
+                  then begin\r
+\r
+                  while (WaitForSingleObject (ProcessInfo.hProcess, 0)) <> WAIT_OBJECT_0 do;\r
+\r
+                  PeekNamedPipe (hRead, nil, 0, nil, @BytesRead, nil);\r
+                  if BytesRead > 0 then begin // pipe not empty\r
+                    ReadFile (hRead, Buffer, 4096, BytesRead, nil);\r
+                    sGPSBabelMsg :=  copy (Buffer, 1, BytesRead);\r
+                    MessageBox (0, pchar (sGPSBabelMsg),'Attention! Message from GPSBabel', MB_OK);\r
+                  end\r
+                  else // pipe is empty\r
+                    MessageDlg ('File conversion complete.', mtInformation, [mbOk], 0);\r
+                end\r
+                else\r
+                  MessageDlg ('Unable to execute GPSBabel.exe.', mtError, [mbOk], 0);\r
+\r
+                CloseHandle (hRead);\r
+                CloseHandle (hWrite);\r
+              end\r
+              else\r
+                MessageDlg ('Unable to create pipe!', mtError, [mbOk], 0);\r
+            end\r
+            else\r
+              MessageDlg ('You must select the output file format.', mtWarning, [mbOk], 0);\r
+          end\r
+          else\r
+            MessageDlg ('Output file is not defined.', mtWarning, [mbOk], 0);\r
+        end\r
+        else\r
+          MessageDlg ('You must select the input file format.', mtWarning, [mbOk], 0);\r
+      end\r
+      else\r
+        MessageDlg ('Input file was not found.', mtWarning, [mbOk], 0);\r
+    end\r
+    else\r
+      MessageDlg ('Input file is not defined.', mtWarning, [mbOk], 0);\r
+  end\r
+  else\r
+    MessageDlg ('Can''t run.', mtError, [mbOk], 0);\r
+end;\r
+\r
+procedure TGPSBabelGUIDialog.btnUseDefaultOutputClick(Sender: TObject);\r
+begin\r
+  if eInput.text <> '' then begin\r
+    if (comboOutput.ItemIndex)> -1 then // Output type is selected\r
+      eOutput.text := LeftStr (eInput.text, AnsiPos (ExtractFileExt (eInput.text), eInput.text)) +\r
+                      GPSDataFormats [comboOutput.ItemIndex].sExt\r
+    else\r
+      MessageDlg ('You must select the output file format.', mtWarning, [mbOk], 0);\r
+  end\r
+  else\r
+    MessageDlg ('Input file is not defined.', mtWarning, [mbOk], 0);\r
+end;\r
+\r
+initialization\r
+end.\r
diff --git a/win32/gui/README.txt b/win32/gui/README.txt
new file mode 100644 (file)
index 0000000..e7f3ff3
--- /dev/null
@@ -0,0 +1,4 @@
+This is a Windows (95/98/NT4/2K/XP) front-end for GPSBabel.\r
+It is a stand-alone program in that it doesn't install any other files or change the registry.\r
+It must able to find GPSBabel; the best place for it is in the same directory as GPSBabel.\r
+Further help is available in GPSBabelGUI.\r
diff --git a/win32/gui/VersionInfo.pas b/win32/gui/VersionInfo.pas
new file mode 100644 (file)
index 0000000..683a135
--- /dev/null
@@ -0,0 +1,99 @@
+unit VersionInfo;\r
+\r
+interface\r
+\r
+uses\r
+       SysUtils, Windows;\r
+\r
+const\r
+       vsComments          = 'Comments';\r
+       vsCompanyName       = 'CompanyName';\r
+       vsFileDescription   = 'FileDescription';\r
+       vsFileVersion       = 'FileVersion';\r
+       vsInternalName      = 'InternalName';\r
+       vsLegalCopyright    = 'LegalCopyright';\r
+       vsLegalTrademarks   = 'LegalTrademarks';\r
+       vsOriginalFilename  = 'OriginalFilename';\r
+       vsPrivateBuild      = 'PrivateBuild';\r
+       vsProductName       = 'ProductName';\r
+       vsProductVersion    = 'ProductVersion';\r
+       vsSpecialBuild      = 'SpecialBuild';\r
+\r
+type\r
+       TFileInfo = (TFileVersion, TFileVersionLong, TProductVersion, TProductVersionLong);\r
+\r
+function GetVersionString (const vsKey: string): string;\r
+function GetFileVersion (const fInfo: TFileInfo): string;\r
+\r
+implementation\r
+\r
+var\r
+       VerInfoPresent: Boolean; // True if "pVersionBuffer" contains valid information\r
+       pVersionBuffer: Pointer; // The file information is stored in this location\r
+\r
+function SwapLong (L: LongInt): LongInt; assembler;\r
+asm\r
+       rol eax, 16;\r
+end;\r
+\r
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+// ex: GetVersionString (vsCompanyName); returns "Down East Engineering"\r
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+function GetVersionString (const vsKey: string): string;\r
+var\r
+       KeyPath: array [0..255] of char;\r
+       p: pointer;\r
+       Len: cardinal;\r
+begin\r
+       Result := '';\r
+       if VerInfoPresent then\r
+               if VerQueryValue (pVersionBuffer, '\VarFileInfo\Translation', p, Len) then begin\r
+                       StrLFmt (KeyPath, 255, '\StringFileInfo\%.8x\%s', [SwapLong (LongInt (p^)), vsKey]);\r
+                       if VerQueryValue (pVersionBuffer, KeyPath, p, Len) then\r
+                               Result := strPas (PChar (p));\r
+               end;\r
+end;\r
+\r
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+// GetFileVersion (TFileVersionLong); returns "1.0.0.0"\r
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+function GetFileVersion (const fInfo: TFileInfo): string;\r
+var\r
+       Len: cardinal;\r
+       pVerInfo: PVSFixedFileInfo;\r
+begin\r
+       Result := '';\r
+       if VerInfoPresent then\r
+               if VerQueryValue (pVersionBuffer, '\', Pointer (pVerInfo), Len) then\r
+                       case fInfo of\r
+                               TFileVersion:\r
+                                       with pVerInfo^ do\r
+                                               Result := Format('%d.%d',\r
+                                                       [dwFileVersionMS shr 16, dwFileVersionMS and $FFFF]);\r
+                               TFileVersionLong:\r
+                                       with pVerInfo^ do\r
+                                               Result := Format('%d.%d.%d.%d',\r
+                                                       [dwFileVersionMS shr 16, dwFileVersionMS and $FFFF,\r
+                                                        dwFileVersionLS shr 16, dwFileVersionLS and $FFFF]);\r
+                       end;\r
+end;\r
+\r
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+// Here is where the information is actually read from the EXE file.\r
+// Data is read once, when the unit is initialized, and stored in 'pVersionBuffer'\r
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+var\r
+       fname: array [0..MAX_PATH] of char;\r
+       bufsize: integer;\r
+       pVersionHandle: cardinal;\r
+\r
+initialization\r
+  StrPLCopy (fname, ParamStr(0), MAX_PATH); // fully qualified Application.ExeName\r
+  bufsize := GetFileVersionInfoSize (fname, pVersionHandle);\r
+  GetMem (pVersionBuffer, bufsize);\r
+  VerInfoPresent := (bufsize > 0) and GetFileVersionInfo (fname, 0, bufsize, pVersionBuffer);\r
+\r
+finalization\r
+  FreeMem (pVersionBuffer, bufsize);\r
+end.\r
+\r
diff --git a/win32/gui/filelist.txt b/win32/gui/filelist.txt
new file mode 100644 (file)
index 0000000..4405fa4
--- /dev/null
@@ -0,0 +1,17 @@
+AboutDialogU.ddp\r
+AboutDialogU.dfm\r
+AboutDialogU.pas\r
+filelist.txt\r
+GPSBabel Windows GUI 2.00.00 Project Plan.pdf\r
+GPSBabelGUI.cfg\r
+GPSBabelGUI.dof\r
+GPSBabelGUI.dpr\r
+GPSBabelGUI.exe\r
+GPSBabelGUI.ico\r
+GPSBabelGUI.res\r
+GPSBabelGUI.todo\r
+GPSBabelGUIDialogU.ddp\r
+GPSBabelGUIDialogU.dfm\r
+GPSBabelGUIDialogU.pas\r
+README.txt\r
+VersionInfo.pas\r
diff --git a/xcsv.c b/xcsv.c
index 80f2ff58f65b3894569000eebc15d522a5f8549b..48acccd899eb278de8acc8b5cc65407d384dadaa 100644 (file)
--- a/xcsv.c
+++ b/xcsv.c
@@ -76,6 +76,7 @@ char_map_t xcsv_char_table[] = {
        { "SPACE",              " "     },
        { "HASH",               "#"     },
        { "WHITESPACE",         "\\w"   },
+       { "PIPE",               "|"     },
        { NULL,                 NULL    }
 };     
 
@@ -166,8 +167,8 @@ xcsv_destroy_style(void)
     xcsv_file.is_internal = internal;
 }
 
-static const char *
-get_char_from_constant_table(char *key)
+const char *
+xcsv_get_char_from_constant_table(char *key)
 {
     char_map_t *cm = xcsv_char_table;
 
@@ -205,7 +206,7 @@ xcsv_parse_style_line(const char *sbuff)
     if (strlen(sbuff)) {
        if (ISSTOKEN(sbuff, "FIELD_DELIMITER")) {
            sp = csv_stringtrim(&sbuff[16], "\"", 1);
-           cp = get_char_from_constant_table(sp);
+           cp = xcsv_get_char_from_constant_table(sp);
            if (cp) {
                xcsv_file.field_delimiter = xstrdup(cp);
                xfree(sp);
@@ -232,7 +233,7 @@ xcsv_parse_style_line(const char *sbuff)
 
        if (ISSTOKEN(sbuff, "RECORD_DELIMITER")) {
            sp = csv_stringtrim(&sbuff[17], "\"", 1);
-           cp = get_char_from_constant_table(sp);
+           cp = xcsv_get_char_from_constant_table(sp);
            if (cp) {
                xcsv_file.record_delimiter = xstrdup(cp);
                xfree(sp);
@@ -291,7 +292,7 @@ xcsv_parse_style_line(const char *sbuff)
 
        if (ISSTOKEN(sbuff, "BADCHARS")) {
            sp = csv_stringtrim(&sbuff[9], "\"", 1);
-           cp = get_char_from_constant_table(sp);
+           cp = xcsv_get_char_from_constant_table(sp);
 
            if (cp) {
                p = xstrdup(cp);
@@ -496,7 +497,7 @@ xcsv_rd_init(const char *fname)
     }
 
     if (global_opts.masked_objective & (TRKDATAMASK|RTEDATAMASK)) {
-       warning(MYNAME "attempting to read %s as a track or route.  Converting to waypoints.\n", fname);
+       warning(MYNAME " attempt to read %s as a track or route, but this module only supports waypoints on read.  Reading as waypoints instead.\n", fname);
     }
 
     xcsv_file.xcsvfp = xfopen(fname, "r", MYNAME);
@@ -562,6 +563,7 @@ xcsv_wr_deinit(void)
 
 ff_vecs_t xcsv_vecs = {
     ff_type_internal,
+    FF_CAP_RW_WPT, /* This is a bit of a lie for now... */
     xcsv_rd_init,
     xcsv_wr_init,
     xcsv_rd_deinit,
diff --git a/xmlgeneric.c b/xmlgeneric.c
new file mode 100644 (file)
index 0000000..9aaf231
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+    Common utilities for XML-based formats.
+
+    Copyright (C) 2004 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include "xmlgeneric.h"
+
+#ifndef NO_EXPAT
+       #include <expat.h>
+       static XML_Parser psr;
+#endif
+
+static vmem_t current_tag;
+static vmem_t cdatastr;
+static FILE *ifd;
+static xg_tag_mapping *xg_tag_tbl;
+
+#define MY_CBUF 4096
+
+#define MYNAME "XML Reader"
+
+void
+write_xml_header(FILE *ofd)
+{
+       fprintf(ofd, "<?xml version=\"1.0\"?>\n");
+}
+
+void
+write_xml_entity(FILE *ofd, const char *indent,
+                 const char *tag, const char *value)
+{
+        char *tmp_ent = xml_entitize(value);
+        fprintf(ofd, "%s<%s>%s</%s>\n", indent, tag, tmp_ent, tag);
+        xfree(tmp_ent);
+}
+
+void
+write_optional_xml_entity(FILE *ofd, const char *indent,
+                          const char *tag, const char *value)
+{
+        if (value && *value)
+                write_xml_entity(ofd, indent, tag, value);
+}
+
+void
+write_xml_entity_begin0(FILE *ofd, const char *indent,
+                                                         const char *tag)
+{
+    fprintf(ofd, "%s<%s>\n", indent, tag);
+}
+
+void
+write_xml_entity_begin1(FILE *ofd, const char *indent,
+                                                         const char *tag, const char *attr,
+                                                         const char *attrval)
+{
+    fprintf(ofd, "%s<%s %s=\"%s\">\n", indent, tag, attr, attrval);
+}
+
+void
+write_xml_entity_begin2(FILE *ofd, const char *indent,
+                                                         const char *tag, const char *attr1,
+                                                         const char *attrval1, const char *attr2,
+                                                         const char *attrval2)
+{
+    fprintf(ofd, "%s<%s %s=\"%s\" %s=\"%s\">\n", indent, tag, attr1, attrval1, attr2, attrval2);
+}
+
+void
+write_xml_entity_end(FILE *ofd, const char *indent,
+                                        const char *tag)
+{
+    fprintf(ofd, "%s</%s>\n", indent, tag);
+}
+
+void
+xml_fill_in_time(char *time_string, const time_t timep, int long_or_short)
+{
+       struct tm *tm = gmtime(&timep);
+       char *format;
+       
+       if (!tm)
+               return;
+       
+       if (long_or_short == XML_LONG_TIME)
+               format = "%02d-%02d-%02dT%02d:%02d:%02dZ";
+       else
+               format = "%02d%02d%02dT%02d%02d%02dZ";
+       sprintf(time_string, format,
+               tm->tm_year+1900, 
+               tm->tm_mon+1, 
+               tm->tm_mday, 
+               tm->tm_hour, 
+               tm->tm_min, 
+               tm->tm_sec);
+}
+
+void
+xml_write_time(FILE *ofd, const time_t timep, char *elname)
+{
+       char time_string[64];
+       xml_fill_in_time(time_string, timep, XML_LONG_TIME);
+       fprintf(ofd, "<%s>%s</%s>\n",
+               elname,
+               time_string,
+               elname
+       );
+
+}
+
+/***********************************************************************
+ * These implement a simple interface for "generic" XML that
+ * maps reasonably close to  1:1 between XML tags and internal data
+ * structures.   
+ * 
+ * It doesn't work well for formats (like GPX) that really are "real"
+ * XML with extended namespaces and such, but it handles many simpler
+ * xml strains and insulates us from a lot of the grubbiness of expat.
+ */
+
+xg_callback *
+xml_tbl_lookup(const char *tag, xg_cb_type cb_type)
+{
+       xg_tag_mapping *tm;
+        for (tm = xg_tag_tbl; tm->tag_cb != NULL; tm++) {
+               if (0 == strcmp(tm->tag_name, tag) && (cb_type == tm->cb_type)) {
+                       return tm->tag_cb;
+               }
+       }
+       return NULL;
+}
+
+
+static void
+xml_start(void *data, const char *el, const char **attr)
+{
+       char *e;
+       char *ep;
+       xg_callback *cb;
+
+       vmem_realloc(&current_tag, strlen(current_tag.mem) + 2 + strlen(el));
+
+       e = current_tag.mem;
+        ep = e + strlen(e);
+        *ep++ = '/';
+        strcpy(ep, el);
+
+       memset(cdatastr.mem, 0, cdatastr.size);
+
+       cb = xml_tbl_lookup(e, cb_start);
+       if (cb) {
+               (*cb)(NULL, attr);
+       }
+}
+
+static void
+xml_cdata(void *dta, const XML_Char *s, int len)
+{
+       char *estr;
+       xg_callback *cb;
+
+       vmem_realloc(&cdatastr,  1 + len + strlen(cdatastr.mem));
+       estr = (char *) cdatastr.mem + strlen(cdatastr.mem);
+       memcpy(estr, s, len);
+       estr[len]  = 0;
+
+       cb = xml_tbl_lookup(current_tag.mem, cb_cdata);
+       if (cb) {
+               (*cb)(estr, NULL);
+       }
+}
+
+static void
+xml_end(void *data, const char *el)
+{
+       char *s = strrchr(current_tag.mem, '/');
+       xg_callback *cb;
+
+       if (strcmp(s + 1, el)) {
+               fprintf(stderr, "Mismatched tag %s\n", el);
+       }
+
+       cb = xml_tbl_lookup(current_tag.mem, cb_end);
+       if (cb) {
+               (*cb)(el, NULL);
+       }
+       *s = 0;
+}
+
+void xml_read(void)
+{
+       int len;
+       char buf[MY_CBUF];
+       
+       while ((len = fread(buf, 1, sizeof(buf), ifd))) {
+               if (!XML_Parse(psr, buf, len, feof(ifd))) {
+                       fatal(MYNAME ":Parse error at %d: %s\n",
+                               XML_GetCurrentLineNumber(psr),
+                               XML_ErrorString(XML_GetErrorCode(psr)));
+               }
+       }
+       XML_ParserFree(psr);
+       
+}
+
+void xml_readstring( char *str ) 
+{
+       int len = strlen(str);
+       if (!XML_Parse(psr, str, len, 1)) {
+               fatal( MYNAME ":Parse error at %d: %s\n",
+                               XML_GetCurrentLineNumber(psr),
+                               XML_ErrorString(XML_GetErrorCode(psr)));
+       }
+       XML_ParserFree(psr);
+}
+
+void
+xml_init(const char *fname, xg_tag_mapping *tbl)
+{
+       if (fname) {
+               ifd = xfopen(fname, "r", MYNAME);
+       }
+
+       current_tag = vmem_alloc(1,0);
+       *((char *)current_tag.mem) = '\0';
+
+       psr = XML_ParserCreate(NULL);
+       if (!psr) {
+               fatal(MYNAME ": Cannot create XML Parser\n");
+       }
+
+       cdatastr = vmem_alloc(1, 0);
+       *((char *)cdatastr.mem) = '\0';
+
+       xg_tag_tbl = tbl;
+
+       XML_SetElementHandler(psr, xml_start, xml_end);
+       XML_SetCharacterDataHandler(psr, xml_cdata);
+}
+
+void
+xml_deinit(void)
+{
+       vmem_free(&current_tag);
+       vmem_free(&cdatastr);
+       if (ifd) {
+               fclose(ifd);
+               ifd = NULL;
+       }
+}
+
+/******************************************/
diff --git a/xmlgeneric.h b/xmlgeneric.h
new file mode 100644 (file)
index 0000000..35758b0
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+    Header for our common utilities for XML-based formats.
+
+    Copyright (C) 2004, 2005 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+
+
+typedef enum {
+       cb_start = 1,
+       cb_cdata,
+       cb_end,
+} xg_cb_type;
+
+typedef void (xg_callback) (const char *, const char **);
+
+typedef struct xg_tag_mapping {
+       xg_callback *tag_cb;
+       xg_cb_type cb_type;
+       const char *tag_name;
+} xg_tag_mapping;
+
+
+void write_xml_entity(FILE *ofd, const char *indent,
+               const char *tag, const char *value);
+void write_xml_entity_begin0(FILE *ofd, const char *indent,
+               const char *tag);
+void write_xml_entity_begin1(FILE *ofd, const char *indent, const char *tag, 
+               const char *attr1, const char *attrval1);
+void write_xml_entity_begin2(FILE *ofd, const char *indent, const char *tag, 
+               const char *attr1, const char *attrval1, 
+               const char *attr2, const char *attrval2);
+void write_xml_entity_end(FILE *ofd, const char *indent, const char *tag);
+
+void write_optional_xml_entity(FILE *ofd, const char *indent,
+               const char *tag, const char *value);
+void xml_write_time(FILE *ofd, const time_t timep, char *elname);
+void xml_fill_in_time(char *time_string, const time_t timep, 
+               int long_or_short);
+void write_xml_header(FILE *ofd);
+
+void xml_init(const char *fname, xg_tag_mapping *tbl);
+void xml_read(void);
+void xml_readstring(char *str);
+void xml_deinit(void);